240 lines
7.4 KiB
Python
240 lines
7.4 KiB
Python
"""Utility functions for the driver."""
|
|
import socket
|
|
import struct
|
|
from Channel import PLCChannel
|
|
import urllib
|
|
import contextlib
|
|
|
|
def get_private_ip_address():
|
|
"""Find the private IP Address of the host device."""
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
try:
|
|
sock.connect(("8.8.8.8", 80))
|
|
except Exception as e:
|
|
return e
|
|
ip_address = sock.getsockname()[0]
|
|
sock.close()
|
|
return ip_address
|
|
|
|
def get_public_ip_address():
|
|
ip_address = "0.0.0.0"
|
|
try:
|
|
with contextlib.closing(urllib.urlopen("http://checkip.amazonaws.com")) as url:
|
|
ip_address = url.read()
|
|
except Exception as e:
|
|
print("could not resolve check IP: {}".format(e))
|
|
return ip_address
|
|
return ip_address[:-1]
|
|
|
|
def int_to_float16(int_to_convert):
|
|
"""Convert integer into float16 representation."""
|
|
bin_rep = ('0' * 16 + '{0:b}'.format(int_to_convert))[-16:]
|
|
sign = 1.0
|
|
if int(bin_rep[0]) == 1:
|
|
sign = -1.0
|
|
exponent = float(int(bin_rep[1:6], 2))
|
|
fraction = float(int(bin_rep[6:17], 2))
|
|
|
|
if exponent == float(0b00000):
|
|
return sign * 2 ** -14 * fraction / (2.0 ** 10.0)
|
|
elif exponent == float(0b11111):
|
|
if fraction == 0:
|
|
return sign * float("inf")
|
|
return float("NaN")
|
|
frac_part = 1.0 + fraction / (2.0 ** 10.0)
|
|
return sign * (2 ** (exponent - 15)) * frac_part
|
|
|
|
|
|
def ints_to_float(int1, int2):
|
|
"""Convert 2 registers into a floating point number."""
|
|
mypack = struct.pack('>HH', int1, int2)
|
|
f_unpacked = struct.unpack('>f', mypack)
|
|
print("[{}, {}] >> {}".format(int1, int2, f_unpacked[0]))
|
|
return f_unpacked[0]
|
|
|
|
|
|
def degf_to_degc(temp_f):
|
|
"""Convert deg F to deg C."""
|
|
return (temp_f - 32.0) * (5.0/9.0)
|
|
|
|
|
|
def degc_to_degf(temp_c):
|
|
"""Convert deg C to deg F."""
|
|
return temp_c * 1.8 + 32.0
|
|
|
|
def get_additional_tags(tag_dict):
|
|
tags_array = tag_dict['additional_tags']
|
|
channel_array = []
|
|
for x in tags_array:
|
|
try:
|
|
print "Making channel {}".format(x)
|
|
channel_array.append(PLCChannel(tag_dict['ip_address'], x['mesh_name'], x['plc_tag'], x['data_type'],x['chg_threshold'],x['guarantee_sec'],plc_type='CLX'))
|
|
except Exception:
|
|
print "Nothing to write or bad key"
|
|
return channel_array
|
|
|
|
def convert_int(plc_tag, value):
|
|
well_status_codes = {
|
|
0: "Running",
|
|
1: "Pumped Off",
|
|
2: "Alarmed",
|
|
3: "Locked Out",
|
|
4: "Stopped"
|
|
}
|
|
|
|
pid_control_codes = {
|
|
0: "Flow",
|
|
1: "Fluid Level",
|
|
2: "Tubing Pressure",
|
|
3: "Manual"
|
|
}
|
|
|
|
downhole_codes = {
|
|
0: "OK",
|
|
1: "Connecting",
|
|
2: "Open Circuit",
|
|
3: "Shorted",
|
|
4: "Cannot Decode"
|
|
}
|
|
|
|
permissive_codes = {
|
|
0: "OK",
|
|
1: "Flow",
|
|
2: "Intake Pressure",
|
|
3: "Intake Temperature",
|
|
4: "Tubing Pressure",
|
|
5: "VFD",
|
|
6: "Fluid Level",
|
|
7: "Min. Downtime"
|
|
}
|
|
|
|
alarm_codes = {
|
|
0: "OK",
|
|
1: "Alarm"
|
|
}
|
|
|
|
alarm_vfd_codes = {
|
|
0: "OK",
|
|
1: "Locked Out"
|
|
}
|
|
|
|
vfd_fault_codes = {
|
|
0: "No Fault",
|
|
2: "Auxiliary Input",
|
|
3: "Power Loss",
|
|
4: "UnderVoltage",
|
|
5: "OverVoltage",
|
|
7: "Motor Overload",
|
|
8: "Heatsink OverTemp",
|
|
9: "Thermister OverTemp",
|
|
10: "Dynamic Brake OverTemp",
|
|
12: "Hardware OverCurrent",
|
|
13: "Ground Fault",
|
|
14: "Ground Warning",
|
|
15: "Load Loss",
|
|
17: "Input Phase Loss",
|
|
18: "Motor PTC Trip",
|
|
19: "Task Overrun",
|
|
20: "Torque Prove Speed Band",
|
|
21: "Output Phase Loss",
|
|
24: "Decel Inhibit",
|
|
25: "OverSpeed Limit",
|
|
26: "Brake Slipped",
|
|
27: "Torque Prove Conflict",
|
|
28: "TP Encls Confict",
|
|
29: "Analog In Loss",
|
|
33: "Auto Restarts Exhausted",
|
|
35: "IPM OverCurrent",
|
|
36: "SW OverCurrent",
|
|
38: "Phase U to Ground",
|
|
39: "Phase V to Ground",
|
|
40: "Phase W to Ground",
|
|
41: "Phase UV Short",
|
|
42: "Phase VW Short",
|
|
43: "Phase WU Short",
|
|
44: "Phase UNeg to Ground",
|
|
45: "Phase VNeg to Ground",
|
|
46: "Phase WNeg to Ground",
|
|
48: "System Defaulted",
|
|
49: "Drive Powerup",
|
|
51: "Clear Fault Queue",
|
|
55: "Control Board Overtemp",
|
|
59: "Invalid Code",
|
|
61: "Shear Pin 1",
|
|
62: "Shear Pin 2",
|
|
64: "Drive Overload",
|
|
66: "OW Torque Level",
|
|
67: "Pump Off",
|
|
71: "Port 1 Adapter",
|
|
72: "Port 2 Adapter",
|
|
73: "Port 3 Adapter",
|
|
74: "Port 4 Adapter",
|
|
75: "Port 5 Adapter",
|
|
76: "Port 6 Adapter",
|
|
77: "IR Volts Range",
|
|
78: "FluxAmps Ref Range",
|
|
79: "Excessive Load",
|
|
80: "AutoTune Aborted",
|
|
81: "Port 1 DPI Loss",
|
|
82: "Port 2 DPI Loss",
|
|
83: "Port 3 DPI Loss",
|
|
84: "Port 4 DPI Loss",
|
|
85: "Port 5 DPI Loss",
|
|
86: "Port 6 DPI Loss",
|
|
87: "IXo Voltage Range",
|
|
91: "Primary Velocity Feedback Loss",
|
|
93: "Hardware Enable Check",
|
|
94: "Alternate Velocity Feedback Loss",
|
|
95: "Auxiliary Velocity Feedback Loss",
|
|
96: "Position Feedback Loss",
|
|
97: "Auto Tach Switch",
|
|
100: "Parameter Checksum",
|
|
101: "Power Down NVS Blank",
|
|
102: "NVS Not Blank",
|
|
103: "Power Down NVS Incompatible",
|
|
104: "Power Board Checksum",
|
|
106: "Incompat MCB-PB",
|
|
107: "Replaced MCB-PB",
|
|
108: "Analog Calibration Checksum",
|
|
110: "Invalid Power Board Data",
|
|
111: "Power Board Invalid ID",
|
|
112: "Power Board App Min Version",
|
|
113: "Tracking DataError",
|
|
115: "Power Down Table Full",
|
|
116: "Power Down Entry Too Large",
|
|
117: "Power Down Data Checksum",
|
|
118: "Power Board Power Down Checksum",
|
|
124: "App ID Changed",
|
|
125: "Using Backup App",
|
|
134: "Start on Power Up",
|
|
137: "External Precharge Error",
|
|
138: "Precharge Open",
|
|
141: "Autotune Enc Angle",
|
|
142: "Autotune Speed Restricted",
|
|
143: "Autotune Current Regulator",
|
|
144: "Autotune Inertia",
|
|
145: "Autotune Travel",
|
|
13035: "Net IO Timeout",
|
|
13037: "Net IO Timeout"
|
|
|
|
}
|
|
|
|
plc_tags = {
|
|
"Device_Status_INT": well_status_codes.get(value, "Invalid Code"),
|
|
"sts_PID_Control": pid_control_codes.get(value, "Invalid Code"),
|
|
"Downhole_Sensor_Status_INT": downhole_codes.get(value, "Invalid Code"),
|
|
"alarm_Flowmeter": alarm_codes.get(value, "Invalid Code"),
|
|
"alarm_IntakePressure": alarm_codes.get(value, "Invalid Code"),
|
|
"alarm_IntakeTemperature": alarm_codes.get(value, "Invalid Code"),
|
|
"alarm_TubingPressure": alarm_codes.get(value, "Invalid Code"),
|
|
"alarm_VFD": alarm_codes.get(value, "Invalid Code"),
|
|
"alarm_Lockout": alarm_vfd_codes.get(value, "Invalid Code"),
|
|
"alarm_FluidLevel": alarm_codes.get(value, "Invalid Code"),
|
|
"Run_Permissive_INT": permissive_codes.get(value, "Invalid Code"),
|
|
"Start_Permissive_INT": permissive_codes.get(value, "Invalid Code"),
|
|
"PowerFlex755.Val_LastFaultCode": vfd_fault_codes.get(value, "Invalid Code"),
|
|
"sts_CurrentVFDFaultCode": vfd_fault_codes.get(value, "Invalid Code")
|
|
}
|
|
|
|
return plc_tags.get(plc_tag, "Invalid Tag")
|
|
|