From 3008541fcee10d09d063dda860232d51bbe8f6e6 Mon Sep 17 00:00:00 2001 From: Nico Melone Date: Tue, 11 Aug 2020 09:04:00 -0500 Subject: [PATCH] updates --- advvfdipp/advvfdippv2/utilities.py | 20 +- advvfdipppond/Channel.py | 298 +++ advvfdipppond/Tags.py | 89 + advvfdipppond/advvfdipppond.py | 214 ++ advvfdipppond/config.txt | 14 + advvfdipppond/file_logger.py | 18 + advvfdipppond/persistence.py | 21 + advvfdipppond/utilities.py | 240 ++ flowmeterskid/Tags.py | 2 +- flowmeterskid/flowmeterskid.py | 23 +- plcfreshwater/config.txt | 2 +- plcfreshwater/plcfreshwater.py | 6 +- promagmbs/modbusMap.json | 512 ++++ promagmbs/modbusMap.p | 3685 +++++++++++--------------- tenflowmeterskid/Tags.py | 143 +- tenflowmeterskid/tenflowmeterskid.py | 39 +- tenflowmeterskid/utilities.py | 24 +- 17 files changed, 3061 insertions(+), 2289 deletions(-) create mode 100644 advvfdipppond/Channel.py create mode 100644 advvfdipppond/Tags.py create mode 100644 advvfdipppond/advvfdipppond.py create mode 100644 advvfdipppond/config.txt create mode 100644 advvfdipppond/file_logger.py create mode 100644 advvfdipppond/persistence.py create mode 100644 advvfdipppond/utilities.py create mode 100644 promagmbs/modbusMap.json diff --git a/advvfdipp/advvfdippv2/utilities.py b/advvfdipp/advvfdippv2/utilities.py index da9df21..8989fee 100644 --- a/advvfdipp/advvfdippv2/utilities.py +++ b/advvfdipp/advvfdippv2/utilities.py @@ -2,15 +2,29 @@ import socket import struct from Channel import PLCChannel +import urllib +import contextlib -def get_public_ip_address(): - """Find the public IP Address of the host device.""" +def get_private_ip_address(): + """Find the private IP Address of the host device.""" sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.connect(("8.8.8.8", 80)) + 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.""" diff --git a/advvfdipppond/Channel.py b/advvfdipppond/Channel.py new file mode 100644 index 0000000..eaf3cbd --- /dev/null +++ b/advvfdipppond/Channel.py @@ -0,0 +1,298 @@ +"""Define Meshify channel class.""" +import time +import urllib +from pycomm.ab_comm.clx import Driver as ClxDriver +from pycomm.cip.cip_base import CommError, DataError +from file_logger import filelogger as log + + + +TAG_DATAERROR_SLEEPTIME = 5 + +def binarray(intval): + """Split an integer into its bits.""" + bin_string = '{0:08b}'.format(intval) + bin_arr = [i for i in bin_string] + bin_arr.reverse() + return bin_arr + + +def read_tag(addr, tag, plc_type="CLX"): + """Read a tag from the PLC.""" + direct = plc_type == "Micro800" + clx = ClxDriver() + try: + if clx.open(addr, direct_connection=direct): + try: + val = clx.read_tag(tag) + clx.close() + return val + except DataError as err: + clx.close() + time.sleep(TAG_DATAERROR_SLEEPTIME) + log.error("Data Error during readTag({}, {}): {}".format(addr, tag, err)) + except CommError: + # err = c.get_status() + clx.close() + log.error("Could not connect during readTag({}, {})".format(addr, tag)) + except AttributeError as err: + clx.close() + log.error("AttributeError during readTag({}, {}): \n{}".format(addr, tag, err)) + clx.close() + return False + + +def read_array(addr, tag, start, end, plc_type="CLX"): + """Read an array from the PLC.""" + direct = plc_type == "Micro800" + clx = ClxDriver() + if clx.open(addr, direct_connection=direct): + arr_vals = [] + try: + for i in range(start, end): + tag_w_index = tag + "[{}]".format(i) + val = clx.read_tag(tag_w_index) + arr_vals.append(round(val[0], 4)) + if arr_vals: + clx.close() + return arr_vals + else: + log.error("No length for {}".format(addr)) + clx.close() + return False + except Exception: + log.error("Error during readArray({}, {}, {}, {})".format(addr, tag, start, end)) + err = clx.get_status() + clx.close() + log.error(err) + clx.close() + + +def write_tag(addr, tag, val, plc_type="CLX"): + """Write a tag value to the PLC.""" + direct = plc_type == "Micro800" + clx = ClxDriver() + try: + if clx.open(addr, direct_connection=direct): + try: + initial_val = clx.read_tag(tag) + write_status = clx.write_tag(tag, val, initial_val[1]) + clx.close() + return write_status + except DataError as err: + clx_err = clx.get_status() + clx.close() + log.error("--\nDataError during writeTag({}, {}, {}, plc_type={}) -- {}\n{}\n".format(addr, tag, val, plc_type, err, clx_err)) + + except CommError as err: + clx_err = clx.get_status() + log.error("--\nCommError during write_tag({}, {}, {}, plc_type={})\n{}\n--".format(addr, tag, val, plc_type, err)) + clx.close() + return False + + +class Channel(object): + """Holds the configuration for a Meshify channel.""" + + def __init__(self, mesh_name, data_type, chg_threshold, guarantee_sec, map_=False, write_enabled=False): + """Initialize the channel.""" + self.mesh_name = mesh_name + self.data_type = data_type + self.last_value = None + self.value = None + self.last_send_time = 0 + self.chg_threshold = chg_threshold + self.guarantee_sec = guarantee_sec + self.map_ = map_ + self.write_enabled = write_enabled + + def __str__(self): + """Create a string for the channel.""" + return "{}\nvalue: {}, last_send_time: {}".format(self.mesh_name, self.value, self.last_send_time) + + def check(self, new_value, force_send=False): + """Check to see if the new_value needs to be stored.""" + send_needed = False + send_reason = "" + if self.data_type == 'BOOL' or self.data_type == 'STRING': + if self.last_send_time == 0: + send_needed = True + send_reason = "no send time" + elif self.value is None: + send_needed = True + send_reason = "no value" + elif self.value != new_value: + if self.map_: + if not self.value == self.map_[new_value]: + send_needed = True + send_reason = "value change" + else: + send_needed = True + send_reason = "value change" + elif (time.time() - self.last_send_time) > self.guarantee_sec: + send_needed = True + send_reason = "guarantee sec" + elif force_send: + send_needed = True + send_reason = "forced" + else: + if self.last_send_time == 0: + send_needed = True + send_reason = "no send time" + elif self.value is None: + send_needed = True + send_reason = "no value" + elif abs(self.value - new_value) > self.chg_threshold: + send_needed = True + send_reason = "change threshold" + elif (time.time() - self.last_send_time) > self.guarantee_sec: + send_needed = True + send_reason = "guarantee sec" + elif force_send: + send_needed = True + send_reason = "forced" + if send_needed: + self.last_value = self.value + if self.map_: + try: + self.value = self.map_[new_value] + except KeyError: + log.error("Cannot find a map value for {} in {} for {}".format(new_value, self.map_, self.mesh_name)) + self.value = new_value + else: + self.value = new_value + self.last_send_time = time.time() + log.info("Sending {} for {} - {}".format(self.value, self.mesh_name, send_reason)) + return send_needed + + def read(self): + """Read the value.""" + pass + + +def identity(sent): + """Return exactly what was sent to it.""" + return sent + + +class ModbusChannel(Channel): + """Modbus channel object.""" + + def __init__(self, mesh_name, register_number, data_type, chg_threshold, guarantee_sec, channel_size=1, map_=False, write_enabled=False, transform_fn=identity): + """Initialize the channel.""" + super(ModbusChannel, self).__init__(mesh_name, data_type, chg_threshold, guarantee_sec, map_, write_enabled) + self.mesh_name = mesh_name + self.register_number = register_number + self.channel_size = channel_size + self.data_type = data_type + self.last_value = None + self.value = None + self.last_send_time = 0 + self.chg_threshold = chg_threshold + self.guarantee_sec = guarantee_sec + self.map_ = map_ + self.write_enabled = write_enabled + self.transform_fn = transform_fn + + def read(self, mbsvalue): + """Return the transformed read value.""" + return self.transform_fn(mbsvalue) + + +class PLCChannel(Channel): + """PLC Channel Object.""" + + def __init__(self, ip, mesh_name, plc_tag, data_type, chg_threshold, guarantee_sec, map_=False, write_enabled=False, plc_type='CLX'): + """Initialize the channel.""" + super(PLCChannel, self).__init__(mesh_name, data_type, chg_threshold, guarantee_sec, map_, write_enabled) + self.plc_ip = ip + self.mesh_name = mesh_name + self.plc_tag = plc_tag + self.data_type = data_type + self.last_value = None + self.value = None + self.last_send_time = 0 + self.chg_threshold = chg_threshold + self.guarantee_sec = guarantee_sec + self.map_ = map_ + self.write_enabled = write_enabled + self.plc_type = plc_type + + def read(self): + """Read the value.""" + plc_value = None + if self.plc_tag and self.plc_ip: + read_value = read_tag(self.plc_ip, self.plc_tag, plc_type=self.plc_type) + if read_value: + plc_value = read_value[0] + + return plc_value + + +class BoolArrayChannels(Channel): + """Hold the configuration for a set of boolean array channels.""" + + def __init__(self, ip, mesh_name, plc_tag, data_type, chg_threshold, guarantee_sec, map_=False, write_enabled=False): + """Initialize the channel.""" + super(BoolArrayChannels, self).__init__(mesh_name, data_type, chg_threshold, guarantee_sec, map_, write_enabled) + self.plc_ip = ip + self.mesh_name = mesh_name + self.plc_tag = plc_tag + self.data_type = data_type + self.last_value = None + self.value = None + self.last_send_time = 0 + self.chg_threshold = chg_threshold + self.guarantee_sec = guarantee_sec + self.map_ = map_ + self.write_enabled = write_enabled + + def compare_values(self, new_val_dict): + """Compare new values to old values to see if the values need storing.""" + send = False + for idx in new_val_dict: + try: + if new_val_dict[idx] != self.last_value[idx]: + send = True + except KeyError: + log.error("Key Error in self.compare_values for index {}".format(idx)) + send = True + return send + + def read(self, force_send=False): + """Read the value and check to see if needs to be stored.""" + send_needed = False + send_reason = "" + if self.plc_tag: + val = read_tag(self.plc_ip, self.plc_tag) + if val: + bool_arr = binarray(val[0]) + new_val = {} + for idx in self.map_: + try: + new_val[self.map_[idx]] = bool_arr[idx] + except KeyError: + log.error("Not able to get value for index {}".format(idx)) + + if self.last_send_time == 0: + send_needed = True + send_reason = "no send time" + elif self.value is None: + send_needed = True + send_reason = "no value" + elif self.compare_values(new_val): + send_needed = True + send_reason = "value change" + elif (time.time() - self.last_send_time) > self.guarantee_sec: + send_needed = True + send_reason = "guarantee sec" + elif force_send: + send_needed = True + send_reason = "forced" + + if send_needed: + self.value = new_val + self.last_value = self.value + self.last_send_time = time.time() + log.info("Sending {} for {} - {}".format(self.value, self.mesh_name, send_reason)) + return send_needed diff --git a/advvfdipppond/Tags.py b/advvfdipppond/Tags.py new file mode 100644 index 0000000..94f957c --- /dev/null +++ b/advvfdipppond/Tags.py @@ -0,0 +1,89 @@ +from Channel import PLCChannel, ModbusChannel +from advvfdipppond import PLC_IP_ADDRESS + +tags = [ + PLCChannel(PLC_IP_ADDRESS, "fm1_flowrate","val_Flowmeter","REAL", 10000, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "fm2_flowrate", "Val_FM2_FR", "REAL", 1000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm3_flowrate", "Val_FM3_FR", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm4_flowrate", "Val_FM4_FR", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm5_flowrate", "Val_FM5_FR", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm6_flowrate", "Val_FM6_FR", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_out_flowrate", "Val_FRTotalOut", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_in_flowrate", "Val_FRTotalIn", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm1_todays", "Flowmeter_Totals.Todays_Totalflow", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm2_todays", "Val_FM2_Todays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm3_todays", "Val_FM3_Todays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm4_todays", "Val_FM4_Todays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm5_todays", "Val_FM5_Todays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm6_todays", "Val_FM6_Todays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_out_todays", "Val_TodaysTotalOut", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_in_todays", "Val_TodaysTotalIn", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm1_yesterdays", "Flowmeter_Totals.Yesterdays_Totalflow", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm2_yesterdays", "Val_FM2_Yesterdays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm3_yesterdays", "Val_FM3_Yesterdays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm4_yesterdays", "Val_FM4_Yesterdays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm5_yesterdays", "Val_FM5_Yesterdays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm6_yesterdays", "Val_FM6_Yesterdays", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_out_yesterdays", "Val_YesterdaysTotalOut", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_in_yesterdays", "Val_YesterdaysTotalIn", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm1_month", "Flowmeter_Totals.CurrentMonth_Totalflow", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm2_month", "Val_FM2_Months", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm3_month", "Val_FM3_Months", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm4_month", "Val_FM4_Months", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm5_month", "Val_FM5_Months", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm6_month", "Val_FM6_Months", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_out_months", "Val_MonthsTotalOut", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_in_months", "Val_MonthsTotalIn", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm1_lastmonths", "Flowmeter_Totals.LastMonth_Totalflow", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm2_lastmonths", "Val_FM2_LastMonths", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm3_lastmonths", "Val_FM3_LastMonths", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm4_lastmonths", "Val_FM4_LastMonths", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm5_lastmonths", "Val_FM5_LastMonths", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "fm6_lastmonths", "Val_FM6_LastMonths", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_out_lastmonths", "Val_LastMonthsTotalOut", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "total_in_lastmonths", "Val_LastMonthsTotalIn", "REAL", 10000, 3600, plc_type='CLX'), + PLCChannel(PLC_IP_ADDRESS, "pond_level","val_FluidLevel","REAL", 2, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "pond_volume","val_PondVolume","REAL", 2, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "intake_pressure","val_IntakePressure","REAL", 10, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "intake_temperature","val_IntakeTemperature","REAL", 5, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "discharge_pressure","val_TubingPressure","REAL", 10, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "pidcontrolmode","sts_PID_Control","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "well_status","Device_Status_INT","INT", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "vfd_frequency","VFD_SpeedFdbk","REAL", 5, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "flowtotal","Flow_Total[0]","REAL", 100, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "energytotal","Energy_Total[0]","REAL", 10, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "vfd_current","VFD_OutCurrent","REAL", 5, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "pump_sensor_status","Downhole_Sensor_Status_INT","INT", 1, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "fluidspecificgravity","cfg_FluidSpecificGravity","REAL", 1, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "flowtotalyesterday","Flow_Total[1]","REAL", 100, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "energytotalyesterday","Energy_Total[1]","REAL", 10, 86400, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_flowrate","alarm_Flowmeter","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_intake_pressure","alarm_IntakePressure","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_intake_temperature","alarm_IntakeTemperature","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_discharge_pressure","alarm_TubingPressure","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_vfd","alarm_VFD","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_lockout","alarm_Lockout","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "run_permissive","Run_Permissive_INT","INT", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "start_permissive","Start_Permissive_INT","INT", 1, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "startcommand","cmd_Start","BOOL", 1, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "stopcommand","cmd_Stop","BOOL", 1, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "flowsetpoint","cfg_PID_FlowSP","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "fluidlevelsetpoint","cfg_PID_FluidLevelSP","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "manualfrequencysetpoint","cfg_PID_ManualSP","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "tubingpressuresetpoint","cfg_PID_TubingPressureSP","REAL", 1, 86400, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_pond_height","alarm_FluidLevel","BOOL", 1, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "pressure_shutdown_limit","AIn_IntakePressure.Val_LoLim","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "pressure_startup_limit","AIn_IntakePressure.Val_HiLim","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "temperature_shutdown_limit","AIn_IntakeTemperature.Val_HiLim","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "temperature_startup_limit","AIn_IntakeTemperature.Val_LoLim","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "sensor_height","cfg_DHSensorDistToIntake","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "last_vfd_fault_code","PowerFlex755.Val_LastFaultCode","INT", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_vfd_fault","sts_CurrentVFDFaultCode","INT", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_io_fault","ControllerFault_IO","BOOL", 1, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "alarm_program_fault","ControllerFault_Program","BOOL", 1, 3600, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "minvfdfrequency","PowerFlex755.Cfg_MinSpdRef","REAL", 1, 86400, plc_type="CLX"), + #PLCChannel(PLC_IP_ADDRESS, "maxvfdfrequency","PowerFlex755.Cfg_MaxSpdRef","REAL", 1, 86400, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "total_out_net","in_HART_Flowmeter_Net","REAL", 100, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "total_out_forward","in_HART_Flowmeter_Fwd","REAL", 100, 3600, plc_type="CLX"), + PLCChannel(PLC_IP_ADDRESS, "total_out_reverse","in_HART_Flowmeter_Rev","REAL", 100, 3600, plc_type="CLX") +] \ No newline at end of file diff --git a/advvfdipppond/advvfdipppond.py b/advvfdipppond/advvfdipppond.py new file mode 100644 index 0000000..0b51d73 --- /dev/null +++ b/advvfdipppond/advvfdipppond.py @@ -0,0 +1,214 @@ +"""Driver for advvfdipppond""" + +import threading +import json +import os +import time +from random import randint +# PERSISTENCE FILE +import persistence +PERSIST = persistence.load("extra_data.json") +if not PERSIST: + PERSIST = {'ip_address': '192.168.1.10', 'download_pycomm': True, 'flowmeter_units': 'GPM'} + persistence.store(PERSIST, "extra_data.json") + os.system('echo "" > /root/python_firmware/drivers/modbusMap.p') +PLC_IP_ADDRESS = PERSIST['ip_address'] +from device_base import deviceBase +import urllib +if PERSIST['download_pycomm']: + try: + urllib.urlretrieve('http://s3.amazonaws.com/pocloud-drivers/pycomm/clx.py', '/root/python_firmware/pycomm/ab_comm/clx.py') + urllib.urlretrieve('http://s3.amazonaws.com/pocloud-drivers/pycomm/cip_base.py', '/root/python_firmware/pycomm/cip/cip_base.py') + PERSIST['download_pycomm'] = False + persistence.store(PERSIST, "extra_data.json") + except Exception as e: + print("Could not download latest pycomm update: {}".format(e)) + +from Channel import PLCChannel, ModbusChannel,read_tag, write_tag, TAG_DATAERROR_SLEEPTIME +from utilities import get_public_ip_address, get_private_ip_address, get_additional_tags, convert_int +from file_logger import filelogger as log +from Tags import tags + + +path = "/root/python_firmware/drivers/additional_tags.py" + +f = open(path, "a+") +f.seek(0) +if os.stat(path).st_size == 0: + f.write("from Channel import PLCChannel, ModbusChannel\n") + f.write("from advvfdipppond import PLC_IP_ADDRESS\n") + f.write("additional_tags = []") +f.close() + + +from additional_tags import additional_tags + +_ = None + +log.info("advvfdipppond startup") + +# GLOBAL VARIABLES +WAIT_FOR_CONNECTION_SECONDS = 30 +IP_CHECK_PERIOD = 60 + +CHANNELS = tags + additional_tags + + +class start(threading.Thread, deviceBase): + """Start class required by Meshify.""" + + def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, + companyId=None, offset=None, mqtt=None, Nodes=None): + """Initialize the driver.""" + threading.Thread.__init__(self) + deviceBase.__init__(self, name=name, number=number, mac=mac, Q=Q, + mcu=mcu, companyId=companyId, offset=offset, + mqtt=mqtt, Nodes=Nodes) + + self.daemon = True + self.version = "1" + self.finished = threading.Event() + self.force_send = False + self.public_ip_address = "" + self.private_ip_address = "" + self.public_ip_address_last_checked = 0 + self.ping_counter = 0 + threading.Thread.start(self) + + # this is a required function for all drivers, its goal is to upload some piece of data + # about your device so it can be seen on the web + def register(self): + """Register the driver.""" + # self.sendtodb("log", "BOOM! Booted.", 0) + pass + + def run(self): + """Actually run the driver.""" + for i in range(0, WAIT_FOR_CONNECTION_SECONDS): + print("advvfdipppond driver will start in {} seconds".format(WAIT_FOR_CONNECTION_SECONDS - i)) + time.sleep(1) + log.info("BOOM! Starting advvfdipppond driver...") + + + + self._check_ip_address() + + self.nodes["advvfdipppond_0199"] = self + try: + if PERSIST['flowmeter_units']: + self.sendtodbDev(1, 'flowunits', PERSIST['flowmeter_units'], 0, 'advvfdipppond') + else: + PERSIST['flowmeter_units'] = "GPM" + persistence.store(PERSIST, "extra_data.json") + self.sendtodbDev(1, 'flowunits', PERSIST['flowmeter_units'], 0, 'advvfdipppond') + except: + PERSIST['flowmeter_units'] = "GPM" + persistence.store(PERSIST, "extra_data.json") + self.sendtodbDev(1, 'flowunits', PERSIST['flowmeter_units'], 0, 'advvfdipppond') + send_loops = 0 + convert_list = ["Device_Status_INT","sts_PID_Control","Downhole_Sensor_Status_INT","alarm_Flowmeter","alarm_IntakePressure", + "alarm_IntakeTemperature","alarm_TubingPressure","alarm_VFD","alarm_Lockout","alarm_FluidLevel","Run_Permissive_INT", + "Start_Permissive_INT","PowerFlex755.Val_LastFaultCode","sts_CurrentVFDFaultCode"] + while True: + now = time.time() + if self.force_send: + log.warning("FORCE SEND: TRUE") + + for chan in CHANNELS: + try: + val = chan.read() + if "hart" in chan.mesh_name and val == None: + val = 0.0 + if chan.check(val, self.force_send): + if chan.plc_tag in convert_list: + converted_value = convert_int(chan.plc_tag, val) + self.sendtodbDev(1, chan.mesh_name, converted_value, 0, 'advvfdipppond') + else: + self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'advvfdipppond') + #time.sleep(TAG_DATAERROR_SLEEPTIME) # sleep to allow Micro800 to handle ENET requests + except Exception as e: + log.info("Error: {}".format(e)) + time.sleep(30) #sleep for 30 seconds after a full poll + # print("advvfdipppond driver still alive...") + if self.force_send: + if send_loops > 2: + log.warning("Turning off force_send") + self.force_send = False + send_loops = 0 + else: + send_loops += 1 + + + if (now - self.public_ip_address_last_checked) > IP_CHECK_PERIOD: + self._check_ip_address() + + + def _check_ip_address(self): + """Check the public IP address and send to Meshify if changed.""" + self.public_ip_address_last_checked = time.time() + test_public_ip = get_public_ip_address() + test_public_ip = test_public_ip + test_private_ip = get_private_ip_address() + if not test_public_ip == self.public_ip_address and not test_public_ip == "0.0.0.0": + self.sendtodbDev(1, 'public_ip_address', test_public_ip, 0, 'advvfdipppond') + self.public_ip_address = test_public_ip + if not test_private_ip == self.private_ip_address: + self.sendtodbDev(1, 'private_ip_address', test_private_ip, 0, 'advvfdipppond') + self.private_ip_address = test_private_ip + hostname = "google.com" + response = 1 + try: + response = os.system("ping -c 1 " + hostname + " > /dev/null 2>&1") + except Exception as e: + print("Something went wrong in ping: {}".format(e)) + + + #and then check the response... + if response == 0: + print hostname, 'is up!' + self.ping_counter = 0 + else: + print hostname, 'is down!' + self.ping_counter += 1 + + if self.ping_counter >= 3: + log.info("Rebooting because no internet detected") + os.system('reboot') + + + def advvfdipppond_sync(self, name, value): + """Sync all data from the driver.""" + self.force_send = True + # self.sendtodb("log", "synced", 0) + return True + + def advvfdipppond_writeplctag(self, name, value): + """Write a value to the PLC.""" + new_val = json.loads(str(value).replace("'", '"')) + tag_n = str(new_val['tag']) # "cmd_Start" + val_n = new_val['val'] + write_res = write_tag(str(PLC_IP_ADDRESS), tag_n, val_n, plc_type="CLX") + print("Result of advvfdipppond_writeplctag(self, {}, {}) = {}".format(name, value, write_res)) + if write_res is None: + write_res = "Error writing to PLC..." + return write_res + + def advvfdipppond_startcmd(self,name, value): + write_res = write_tag(str(PLC_IP_ADDRESS), "cmd_Start" , 1, plc_type="CLX") + print("Result of advvfdipppond_writeplctag(self, {}, {}) = {}".format(name, value, write_res)) + if write_res is None: + write_res = "Error writing to PLC..." + return write_res + + def advvfdipppond_stopcmd(self,name, value): + write_res = write_tag(str(PLC_IP_ADDRESS), "cmd_Stop" , 1, plc_type="CLX") + print("Result of advvfdipppond_writeplctag(self, {}, {}) = {}".format(name, value, write_res)) + if write_res is None: + write_res = "Error writing to PLC..." + return write_res + + def advvfdipppond_flowunits(self, name, value): + new_val = json.loads(str(value).replace("'", '"')) + PERSIST['flowmeter_units'] = new_val + persistence.store(PERSIST, "extra_data.json") + self.sendtodbDev(1, 'flowunits', PERSIST['flowmeter_units'], 0, 'advvfdipppond') \ No newline at end of file diff --git a/advvfdipppond/config.txt b/advvfdipppond/config.txt new file mode 100644 index 0000000..1c03c6c --- /dev/null +++ b/advvfdipppond/config.txt @@ -0,0 +1,14 @@ +{ + "files": { + "file3": "file_logger.py", + "file2": "Channel.py", + "file1": "advvfdipppond.py", + "file6": "persistence.py", + "file5": "utilities.py", + "file4": "Tags.py" + }, + "deviceName": "advvfdipppond", + "releaseVersion": "1", + "driverFileName": "advvfdipppond.py", + "driverId": "0100" +} \ No newline at end of file diff --git a/advvfdipppond/file_logger.py b/advvfdipppond/file_logger.py new file mode 100644 index 0000000..cb01d2c --- /dev/null +++ b/advvfdipppond/file_logger.py @@ -0,0 +1,18 @@ +"""Logging setup for advvfdipp""" +import logging +from logging.handlers import RotatingFileHandler +import sys + +log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(funcName)s(%(lineno)d) %(message)s') +log_file = './advvfdipppond.log' +my_handler = RotatingFileHandler(log_file, mode='a', maxBytes=500*1024, + backupCount=2, encoding=None, delay=0) +my_handler.setFormatter(log_formatter) +my_handler.setLevel(logging.INFO) +filelogger = logging.getLogger('advvfdipppond') +filelogger.setLevel(logging.INFO) +filelogger.addHandler(my_handler) + +console_out = logging.StreamHandler(sys.stdout) +console_out.setFormatter(log_formatter) +filelogger.addHandler(console_out) diff --git a/advvfdipppond/persistence.py b/advvfdipppond/persistence.py new file mode 100644 index 0000000..8c8703f --- /dev/null +++ b/advvfdipppond/persistence.py @@ -0,0 +1,21 @@ +"""Data persistance functions.""" +# if more advanced persistence is needed, use a sqlite database +import json + + +def load(filename="persist.json"): + """Load persisted settings from the specified file.""" + try: + with open(filename, 'r') as persist_file: + return json.load(persist_file) + except Exception: + return False + + +def store(persist_obj, filename="persist.json"): + """Store the persisting settings into the specified file.""" + try: + with open(filename, 'w') as persist_file: + return json.dump(persist_obj, persist_file, indent=4) + except Exception: + return False diff --git a/advvfdipppond/utilities.py b/advvfdipppond/utilities.py new file mode 100644 index 0000000..8989fee --- /dev/null +++ b/advvfdipppond/utilities.py @@ -0,0 +1,240 @@ +"""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") + \ No newline at end of file diff --git a/flowmeterskid/Tags.py b/flowmeterskid/Tags.py index 2c9954d..4cc4469 100644 --- a/flowmeterskid/Tags.py +++ b/flowmeterskid/Tags.py @@ -15,7 +15,7 @@ tags = [ PLCChannel(PLC_IP_ADDRESS, "val_fm2_fr","val_fm2_fr","REAL", 5, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "val_fm2_t1","val_fm2_t1","REAL", 50, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "val_fm2_t2","val_fm2_t2","REAL", 50, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "val_fm2_t3","val_fm2_t3","REAL", 50, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "val_fm2_t3","val_fm3_t3","REAL", 50, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "val_fm2_yesterday","val_fm2_yesterday","REAL", 100, 86400, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "val_fm2_today","val_fm2_today","REAL", 25, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "val_fm2_lastmonth","val_fm2_lastmonth","REAL", 100, 86400, plc_type="Micro800"), diff --git a/flowmeterskid/flowmeterskid.py b/flowmeterskid/flowmeterskid.py index 34161e6..3540a19 100644 --- a/flowmeterskid/flowmeterskid.py +++ b/flowmeterskid/flowmeterskid.py @@ -26,7 +26,11 @@ CHANNELS = tags # PERSISTENCE FILE PERSIST = persistence.load() - +if not PERSIST: + PERSIST = { + "ignore_list": [] + } + persistence.store(PERSIST) class start(threading.Thread, deviceBase): """Start class required by Meshify.""" @@ -75,7 +79,10 @@ class start(threading.Thread, deviceBase): for chan in CHANNELS: val = chan.read() if chan.check(val, self.force_send): - self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'flowmeterskid') + if chan.mesh_name in PERSIST["ignore_list"]: + self.sendtodbDev(1, chan.mesh_name, None, 0, 'flowmeterskid') + else: + self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'flowmeterskid') #time.sleep(TAG_DATAERROR_SLEEPTIME) # sleep to allow Micro800 to handle ENET requests # print("flowmeterskid driver still alive...") @@ -131,3 +138,15 @@ class start(threading.Thread, deviceBase): if write_res is None: write_res = "Error writing to PLC..." return write_res + + def flowmeterskid_ignorechannel(self, name, value): + if value not in PERSIST["ignore_list"]: + PERSIST["ignore_list"].append(value) + persistence.store(PERSIST) + return True + + def flowmeterskid_observechannel(self, name, value): + if value in PERSIST["ignore_list"]: + PERSIST["ignore_list"].remove(value) + persistence.store(PERSIST) + return True diff --git a/plcfreshwater/config.txt b/plcfreshwater/config.txt index 877fef1..1e8d413 100644 --- a/plcfreshwater/config.txt +++ b/plcfreshwater/config.txt @@ -8,7 +8,7 @@ "file4": "Tags.py" }, "deviceName": "plcfreshwater", - "releaseVersion": "11", + "releaseVersion": "12", "driverFileName": "plcfreshwater.py", "driverId": "0100" } \ No newline at end of file diff --git a/plcfreshwater/plcfreshwater.py b/plcfreshwater/plcfreshwater.py index 3c5d1ee..0d55e03 100644 --- a/plcfreshwater/plcfreshwater.py +++ b/plcfreshwater/plcfreshwater.py @@ -53,7 +53,7 @@ class start(threading.Thread, deviceBase): mqtt=mqtt, Nodes=Nodes) self.daemon = True - self.version = "11" + self.version = "12" self.finished = threading.Event() self.force_send = False self.public_ip_address = "" @@ -276,11 +276,11 @@ class start(threading.Thread, deviceBase): #if a comms error use the stored values else use the latested values if val == None: PERSIST['Previous Months'] = PERSIST['Current Months'] - PERSIST['Current Month'] = 0 + PERSIST['Current Months'] = 0 PERSIST['Monthly Holding'] = PERSIST['Lifetime'] else: PERSIST['Previous Months'] = val - PERSIST['Monthly Holding'] - PERSIST['Current Month'] = 0 + PERSIST['Current Months'] = 0 PERSIST['Monthly Holding'] = val PERSIST['Month'] = month self.sendtodbDev(1, 'total_fm_month_gal', PERSIST['Current Months'], 0, 'plcfreshwater') diff --git a/promagmbs/modbusMap.json b/promagmbs/modbusMap.json new file mode 100644 index 0000000..7e83046 --- /dev/null +++ b/promagmbs/modbusMap.json @@ -0,0 +1,512 @@ +{ + "1": { + "c": "M1-485", + "b": "9600", + "addresses": { + "2": { + "4-1": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Volume Flow", + "ct": "number", + "le": "32", + "grp": "600", + "la": 0.0, + "chn": "volume_flow", + "un": "1", + "dn": "promagmbs", + "da": "2", + "lrt": 1515775636.862535, + "a": "2008", + "c": "5", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-1", + "mv": "0", + "s": "On", + "r": "0-100000", + "t": "floatbs", + "vm": null + }, + "4-3": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Conductivity", + "ct": "number", + "le": "32", + "grp": "600", + "la": NaN, + "chn": "conductivity", + "un": "1", + "dn": "promagmbs", + "da": "2", + "lrt": 1515775621.262141, + "a": "2012", + "c": "0.5", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-3", + "mv": "0", + "s": "On", + "r": "0-10000", + "t": "floatbs", + "vm": null + }, + "4-4": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Totalizer 1", + "ct": "number", + "le": "32", + "grp": "600", + "la": 245249.88, + "chn": "totalizer_1", + "un": "1", + "dn": "promagmbs", + "da": "2", + "lrt": 1515775638.257201, + "a": "2609", + "c": "50.0", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-4", + "mv": "0", + "s": "On", + "r": "0-10000000", + "t": "floatbs", + "vm": null + }, + "4-5": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Totalizer 2", + "ct": "number", + "le": "32", + "grp": "600", + "la": 265849.72, + "chn": "totalizer_2", + "un": "1", + "dn": "promagmbs", + "da": "2", + "lrt": 1515775574.650748, + "a": "2809", + "c": "50", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-5", + "mv": "0", + "s": "On", + "r": "0-10000000", + "t": "floatbs", + "vm": null + }, + "4-6": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Totalizer 3", + "ct": "number", + "le": "32", + "grp": "600", + "la": 0, + "chn": "totalizer_3", + "un": "1", + "dn": "promagmbs", + "da": "2", + "lrt": 1515624472.5080974, + "r": "-10000000-10000000", + "a": "3009", + "c": "50", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-6", + "s": "On", + "mv": "0", + "t": "floatbs", + "vm": null + }, + "4-7": { + "ah": "", + "bytary": null, + "al": "", + "vn": "Volume Flow Units", + "ct": "number", + "le": "16", + "grp": "86400", + "la": 45, + "chn": "volume_flow_units", + "un": "1", + "dn": "promagmbs", + "da": "2", + "lrt": 1515711271.343798, + "a": "2102", + "c": "0", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-7", + "mv": "0", + "s": "On", + "r": "0-100", + "t": "int", + "vm": { + "24": "Ml/s", + "25": "Ml/min", + "26": "Ml/h", + "27": "Ml/d", + "20": "hl/s", + "21": "hl/min", + "22": "hl/h", + "23": "hl/d", + "0": "cm3/s", + "4": "dm3/s", + "8": "m3/s", + "59": "BBL/d (US beer)", + "58": "BBL/h (US beer)", + "55": "BBL/d (US liq.)", + "54": "BBL/h (US liq.)", + "57": "BBL/min (US beer)", + "56": "BBL/s (US beer)", + "51": "Mgal/d", + "50": "Mgal/h", + "53": "BBL/min (US liq.)", + "52": "BBL/s (US liq.)", + "88": "kgal/s (us)", + "89": "kgal/min (us)", + "82": "BBL/h (imp oil)", + "83": "BBL/d (imp oil)", + "80": "BBL/s (imp oil)", + "81": "BBL/min (imp oil)", + "86": "User vol / hour", + "87": "User vol / day", + "84": "User vol / s", + "85": "User vol / min", + "3": "cm3/d", + "7": "dm3/d", + "39": "ft3/d", + "38": "ft3/h", + "33": "af/min", + "32": "af/s", + "37": "ft3/min", + "36": "ft3/s", + "35": "af/d", + "34": "af/h", + "60": "BBL/s (US oil)", + "61": "BBL/min (US oil)", + "62": "BBL/h (US oil)", + "63": "BBL/d (US oil)", + "64": "BBL/s (US tank)", + "65": "BBL/min (US tank)", + "66": "BBL/h (US tank)", + "67": "BBL/d (US tank)", + "68": "gal/s (imp)", + "69": "gal/min (imp)", + "2": "cm3/h", + "6": "dm3/h", + "91": "kgal/d (us)", + "90": "kgal/h (us)", + "11": "m3/d", + "10": "m3/h", + "13": "mL/min", + "12": "mL/s", + "15": "mL/d", + "14": "mL/h", + "17": "l/min", + "16": "l/s", + "19": "l/d", + "18": "l/h", + "48": "Mgal/s", + "49": "Mgal/min", + "46": "gal/h", + "47": "gal/d", + "44": "gal/s", + "45": "gal/min", + "42": "fl oz/h", + "43": "fl oz/d", + "40": "fl oz/s", + "41": "fl oz/min", + "1": "cm3/min", + "5": "dm3/min", + "9": "m3/min", + "77": "BBL/min (imp beer)", + "76": "BBL/s (imp beer)", + "75": "Mgal/d (imp)", + "74": "Mgal/h (imp)", + "73": "Mgal/min (imp)", + "72": "Mgal/s (imp)", + "71": "gal/d (imp)", + "70": "gal/h (imp)", + "79": "BBL/d (imp beer)", + "78": "BBL/h (imp beer)" + } + }, + "4-8": { + "r": "0-22", + "ah": "", + "bytary": null, + "al": "", + "vn": "Volume Units", + "ct": "number", + "le": "16", + "grp": "86400", + "la": 11, + "chn": "", + "un": "", + "dn": "M1", + "vm": { + "20": "BBL (imp oil)", + "21": "User vol.", + "22": "kgal (us)", + "1": "dm3", + "0": "cm3", + "3": "ml", + "2": "m3", + "5": "hl", + "4": "l", + "6": "Ml Mega", + "9": "ft3", + "8": "af", + "11": "gal (us)", + "10": "fl oz (us)", + "13": "BBL (US liq)", + "12": "Mgal (us)", + "15": "BBL (US oil)", + "14": "BBL (US beer)", + "17": "gal (imp)", + "16": "BBL (US tank)", + "19": "BBL (imp beer)", + "18": "Mgal (imp)" + }, + "lrt": 1515711271.8358026, + "da": "2", + "a": "2103", + "c": "0", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-8", + "s": "On", + "mv": "0", + "t": "int" + }, + "4-9": { + "ah": "", + "bytary": null, + "al": "", + "vn": "Conductivity Unit", + "ct": "number", + "le": "16", + "grp": "86400", + "la": 8, + "chn": "", + "un": "", + "dn": "M1", + "vm": null, + "lrt": 1515711272.327509, + "da": "2", + "a": "2120", + "c": "0", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-9", + "mv": "0", + "s": "On", + "r": "0-10", + "t": "int" + }, + "4-12": { + "r": "0-56", + "ah": "", + "bytary": null, + "al": "", + "vn": "Totalizer 1 Units", + "ct": "number", + "le": "16", + "grp": "86400", + "la": 11, + "chn": "totalizer_1_units", + "un": "1", + "dn": "promagmbs", + "vm": { + "20": "BBL (imp oil)", + "21": "User vol.", + "22": "kGal (us)", + "1": "dm3", + "0": "cm3", + "3": "ml", + "2": "m3", + "5": "hl", + "4": "l", + "6": "Ml Mega", + "9": "ft3", + "8": "af", + "11": "gal (us)", + "10": "fl oz (us)", + "13": "BBL (US liq)", + "12": "Mgal (us)", + "15": "BBL (US oil)", + "14": "BBL (US beer)", + "17": "gal (imp)", + "16": "BBL (US tank)", + "19": "BBL (imp beer)", + "18": "Mgal (imp)", + "56": "User mass", + "51": "kg", + "50": "g", + "53": "oz", + "52": "t", + "55": "STon", + "54": "lb" + }, + "lrt": 1515711272.82556, + "da": "2", + "a": "4603", + "c": "0", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-12", + "s": "On", + "mv": "0", + "t": "int" + }, + "4-13": { + "ah": "", + "bytary": null, + "al": "", + "vn": "Totalizer 2 Units", + "ct": "number", + "le": "16", + "grp": "86400", + "la": 11, + "chn": "totalizer_2_units", + "un": "1", + "dn": "promagmbs", + "vm": { + "20": "BBL (imp oil)", + "21": "User vol.", + "22": "kGal (us)", + "1": "dm3", + "0": "cm3", + "3": "ml", + "2": "m3", + "5": "hl", + "4": "l", + "6": "Ml Mega", + "9": "ft3", + "8": "af", + "11": "gal (us)", + "10": "fl oz (us)", + "13": "BBL (US liq)", + "12": "Mgal (us)", + "15": "BBL (US oil)", + "14": "BBL (US beer)", + "17": "gal (imp)", + "16": "BBL (US tank)", + "19": "BBL (imp beer)", + "18": "Mgal (imp)", + "56": "User mass", + "51": "kg", + "50": "g", + "53": "oz", + "52": "t", + "55": "STon", + "54": "lb" + }, + "lrt": 1515711273.323234, + "da": "2", + "a": "4604", + "c": "0", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-13", + "mv": "0", + "s": "On", + "r": "0-56", + "t": "int" + }, + "4-14": { + "ah": "", + "bytary": null, + "al": "", + "vn": "Totalizer 3 Units", + "ct": "number", + "le": "16", + "grp": "86400", + "la": 11, + "chn": "totalizer_3_units", + "un": "1", + "dn": "promagmbs", + "vm": { + "20": "BBL (imp oil)", + "21": "User vol.", + "22": "kGal (us)", + "1": "dm3", + "0": "cm3", + "3": "ml", + "2": "m3", + "5": "hl", + "4": "l", + "6": "Ml Mega", + "9": "ft3", + "8": "af", + "11": "gal (us)", + "10": "fl oz (us)", + "13": "BBL (US liq)", + "12": "Mgal (us)", + "15": "BBL (US oil)", + "14": "BBL (US beer)", + "17": "gal (imp)", + "16": "BBL (US tank)", + "19": "BBL (imp beer)", + "18": "Mgal (imp)", + "56": "User mass", + "51": "kg", + "50": "g", + "53": "oz", + "52": "t", + "55": "STon", + "54": "lb" + }, + "lrt": 1515711273.829602, + "da": "2", + "a": "4605", + "c": "0", + "misc_u": "", + "f": "3", + "mrt": "60", + "m": "none", + "m1ch": "4-14", + "mv": "0", + "s": "On", + "r": "0-56", + "t": "int" + } + } + }, + "f": "Off", + "p": "None", + "s": "2" + } +} \ No newline at end of file diff --git a/promagmbs/modbusMap.p b/promagmbs/modbusMap.p index 4d3ac82..94aad95 100644 --- a/promagmbs/modbusMap.p +++ b/promagmbs/modbusMap.p @@ -1,86 +1,83 @@ (dp0 -S'1' +V1 p1 (dp2 -S'c' +Vc p3 VM1-485 p4 -sS'b' +sVb p5 V9600 p6 -sS'addresses' +sVaddresses p7 (dp8 -V1 +V2 p9 (dp10 -V2-2 +V4-1 p11 (dp12 -Vr +Vah p13 -V0-65535 -p14 -sVah -p15 V -p16 +p14 sVbytary -p17 +p15 NsVal -p18 -g16 +p16 +V0 +p17 sVvn +p18 +VVolume Flow p19 -VRaw Battery Terminal Voltage -p20 sVct -p21 +p20 Vnumber -p22 +p21 sVle +p22 +V32 p23 -V16 -p24 sVgrp -p25 +p24 V600 -p26 +p25 sVla -p27 -I20046 +p26 +F0.0 sVchn +p27 +Vvolume_flow p28 -Vadc_vbterm_raw -p29 sVun +p29 +V1 p30 -g9 sVdn p31 -Vprostarsolar +Vpromagmbs p32 -sVvm -p33 -NsVlrt -p34 -F1515775290.9225079 sVda +p33 +V2 +p34 +sVlrt p35 -g9 +F1515775636.8625349 sVa p36 -V18 +V2008 p37 sVc p38 -V0 +V5 p39 sVmisc_u p40 -g16 +g14 sVf p41 V3 @@ -95,1274 +92,1048 @@ Vnone p46 sVm1ch p47 -g11 -sVs -p48 -VOn -p49 -sVmv -p50 -g39 -sVt -p51 -Vint -p52 -ssV2-3 -p53 -(dp54 -Vah -p55 -g16 -sVbytary -p56 -NsVal -p57 -g16 -sVvn -p58 -VRaw Array Voltage -p59 -sVct -p60 -Vnumber -p61 -sVle -p62 -V16 -p63 -sVgrp -p64 -V600 -p65 -sVla -p66 -I19750 -sVchn -p67 -Vadc_va_raw -p68 -sVun -p69 -g9 -sVdn -p70 -Vprostarsolar -p71 -sVvm -p72 -NsVlrt -p73 -F1515775567.9501009 -sVda -p74 -g9 -sg36 -V19 -p75 -sg38 -g39 -sVmisc_u -p76 -g16 -sg41 -g42 -sVmrt -p77 -V60 -p78 -sg45 -Vnone -p79 -sS'm1ch' -p80 -g53 -sVmv -p81 -g39 -sg48 -VOn -p82 -sg13 -V0-65535 -p83 -sg51 -Vint -p84 -ssV2-1 -p85 -(dp86 -Vah -p87 -g16 -sVbytary -p88 -NsVal -p89 -g16 -sVvn -p90 -VRaw Array Current -p91 -sVct -p92 -Vnumber -p93 -sVle -p94 -V16 -p95 -sVgrp -p96 -V600 -p97 -sVla -p98 -I35208 -sVchn -p99 -Vadc_ia_raw -p100 -sVun -p101 -g9 -sVdn -p102 -Vprostarsolar -p103 -sVvm -p104 -NsVlrt -p105 -F1515775632.3861569 -sVda -p106 -g9 -sg36 -V17 -p107 -sg38 -g9 -sVmisc_u -p108 -g16 -sg41 -g42 -sVmrt -p109 -V60 -p110 -sg45 -Vnone -p111 -sg80 -g85 -sVmv -p112 -g39 -sg48 -VOn -p113 -sg13 -V0-65535 -p114 -sg51 -Vint -p115 -ssV2-6 -p116 -(dp117 -Vah -p118 -g16 -sVbytary -p119 -NsVal -p120 -g16 -sVvn -p121 -VRaw Ambient Temp -p122 -sVct -p123 -Vnumber -p124 -sVle -p125 -V16 -p126 -sVgrp -p127 -V600 -p128 -sVla -p129 -I19672 -sVchn -p130 -Vt_amb_raw -p131 -sVun -p132 -g9 -sVdn -p133 -Vprostarsolar -p134 -sVvm -p135 -NsVlrt -p136 -F1515775649.7532052 -sVda -p137 -g9 -sg36 -V28 -p138 -sg38 -g39 -sVmisc_u -p139 -g16 -sg41 -g42 -sVmrt -p140 -V60 -p141 -sg45 -Vnone -p142 -sg80 -g116 -sVmv -p143 -g39 -sg48 -VOn -p144 -sg13 -V0-65535 -p145 -sg51 -Vint -p146 -ssV2-7 -p147 -(dp148 -Vah -p149 -g16 -sVbytary -p150 -NsVal -p151 -g16 -sVvn -p152 -VRaw Min Daily Battery Voltage -p153 -sVct -p154 -Vnumber -p155 -sVle -p156 -V16 -p157 -sVgrp -p158 -V600 -p159 -sVla -p160 -I20045 -sVchn -p161 -Vvb_min_daily_raw -p162 -sVun -p163 -g9 -sVdn -p164 -Vprostarsolar -p165 -sVvm -p166 -NsVlrt -p167 -F1515775097.6945859 -sVda -p168 -g9 -sg36 -V65 -p169 -sg38 -g39 -sVmisc_u -p170 -g16 -sg41 -g42 -sVmrt -p171 -V60 -p172 -sg45 -Vnone -p173 -sg80 -g147 -sVmv -p174 -g39 -sg48 -VOn -p175 -sg13 -V0-65535 -p176 -sg51 -Vint -p177 -ssV2-4 -p178 -(dp179 -Vah -p180 -g16 -sVbytary -p181 -NsVal -p182 -g16 -sVvn -p183 -VRaw Load Voltage -p184 -sVct -p185 -Vnumber -p186 -sVle -p187 -V16 -p188 -sVgrp -p189 -V600 -p190 -sVla -p191 -I20047 -sVchn -p192 -Vadc_vl_raw -p193 -sVun -p194 -g9 -sVdn -p195 -Vprostarsolar -p196 -sVvm -p197 -NsVlrt -p198 -F1515775666.2369889 -sVda -p199 -g9 -sg36 -V20 -p200 -sg38 -g39 -sVmisc_u -p201 -g16 -sg41 -g42 -sVmrt -p202 -V60 -p203 -sg45 -Vnone -p204 -sg80 -g178 -sVmv -p205 -g39 -sg48 -VOn -p206 -sg13 -V0-65535 -p207 -sg51 -Vint -p208 -ssV2-5 -p209 -(dp210 -Vah -p211 -g16 -sVbytary -p212 -NsVal -p213 -g16 -sVvn -p214 -VRaw Load Current -p215 -sVct -p216 -Vnumber -p217 -sVle -p218 -V16 -p219 -sVgrp -p220 -V600 -p221 -sVla -p222 -I12292 -sVchn -p223 -Vadc_il_raw -p224 -sVun -p225 -g9 -sVdn -p226 -Vprostarsolar -p227 -sVvm -p228 -NsVlrt -p229 -F1515775618.7710589 -sVda -p230 -g9 -sg36 -V22 -p231 -sg38 -g39 -sVmisc_u -p232 -g16 -sg41 -g42 -sVmrt -p233 -V60 -p234 -sg45 -Vnone -p235 -sg80 -g209 -sVmv -p236 -g39 -sg48 -VOn -p237 -sg13 -V0-65535 -p238 -sg51 -Vint -p239 -ssV2-8 -p240 -(dp241 -Vah -p242 -g16 -sVbytary -p243 -NsVal -p244 -g16 -sVvn -p245 -VRaw Max Daily Battery Voltage -p246 -sVct -p247 -Vnumber -p248 -sVle -p249 -V16 -p250 -sVgrp -p251 -V600 -p252 -sVla -p253 -I20058 -sVchn -p254 -Vvb_max_daily_raw -p255 -sVun -p256 -g9 -sVdn -p257 -Vprostarsolar -p258 -sVvm -p259 -NsVlrt -p260 -F1515775181.078918 -sVda -p261 -g9 -sg36 -V66 -p262 -sg38 -g39 -sVmisc_u -p263 -g16 -sg41 -g42 -sVmrt -p264 -V60 -p265 -sg45 -Vnone -p266 -sg80 -g240 -sVmv -p267 -g39 -sg48 -VOn -p268 -sg13 -V0-65535 -p269 -sg51 -Vint -p270 -ssV2-9 -p271 -(dp272 -Vah -p273 -g16 -sVbytary -p274 -NsVal -p275 -g16 -sVvn -p276 -VCharge State -p277 -sVct -p278 -Vnumber -p279 -sVle -p280 -V16 -p281 -sVgrp -p282 -V600 -p283 -sVla -p284 -I1 -sVchn -p285 -Vcharge_state -p286 -sVun -p287 -g9 -sVdn -p288 -Vprostarsolar -p289 -sVvm -p290 -(dp291 -g9 -VNight Check -p292 -sg39 -VStart -p293 -sg42 -VNight -p294 -sV2 -p295 -VDisconnect -p296 -sV5 -p297 -VBulk -p298 -sV4 -p299 -VFault -p300 -sV7 -p301 -VFloat -p302 -sV6 -p303 -VAbsorption -p304 -sV8 -p305 -VEqualize -p306 -ssVlrt -p307 -F1515775635.6964082 -sVda -p308 -g9 -sg36 -V33 -p309 -sg38 -g39 -sVmisc_u -p310 -g16 -sg41 -g42 -sVmrt -p311 -V60 -p312 -sg45 -Vnone -p313 -sg80 -g271 -sVmv -p314 -g39 -sg48 -VOn -p315 -sg13 -V0-65535 -p316 -sg51 -Vint -p317 -ssV2-10 -p318 -(dp319 -Vah -p320 -g16 -sVbytary -p321 -NsVal -p322 -g16 -sVvn -p323 -VArray Fault -p324 -sVct -p325 -Vnumber -p326 -sVle -p327 -V16 -p328 -sVgrp -p329 -V600 -p330 -sVla -p331 -I0 -sVchn -p332 -Varray_fault -p333 -sVun -p334 -g9 -sVdn -p335 -Vprostarsolar -p336 -sVvm -p337 -(dp338 -V11 -p339 -VProcessor Supply Fault -p340 -sV10 -p341 -VDip Switch Changed (Excl. DIP 8) -p342 -sg9 -VFETs Shorted -p343 -sg39 -VOvercurrent Phase 1 -p344 -sg42 -VBattery HVD (High Voltage Disconnect) -p345 -sg295 -VSoftware Bug -p346 -sg297 -VEEPROM Setting Edit (Reset required) -p347 -sg299 -VArray HVD (High Voltage Disconnect) -p348 -sg301 -VRTS was valid now disconnected -p349 -sg303 -VRTS Shorted -p350 -sV9 -p351 -VBattery LVD (Low Voltage Disconnect) -p352 -sg305 -VLocal temp. sensor failed -p353 -ssVlrt -p354 -F1515775246.5188161 -sVda -p355 -g9 -sg36 -V34 -p356 -sg38 -g39 -sVmisc_u -p357 -g16 -sg41 -g42 -sVmrt -p358 -V60 -p359 -sg45 -Vnone -p360 -sg80 -g318 -sVmv -p361 -g39 -sg48 -VOn -p362 -sg13 -V0-65535 -p363 -sg51 -Vint -p364 -ssssS'f' -p365 -VOff -p366 -sS'p' -p367 -g16 -sS's' -p368 -V2 -p369 -ssS'2' -p370 -(dp371 -g3 -VM1-485 -p372 -sg5 -V9600 -p373 -sg7 -(dp374 -g295 -(dp375 V4-1 -p376 -(dp377 -Vr -p378 -V0-100000 -p379 -sVah -p380 -g16 -sVbytary -p381 -NsVal -p382 -V0 -p383 -sVvn -p384 -VVolume Flow -p385 -sVct -p386 -Vnumber -p387 -sVle -p388 -V32 -p389 -sVgrp -p390 -V600 -p391 -sVla -p392 -F0.0 -sVchn -p393 -Vvolume_flow -p394 -sVun -p395 -V1 -p396 -sVdn -p397 -Vpromagmbs -p398 -sVvm -p399 -NsVlrt -p400 -F1515775636.8625349 -sVda -p401 -g369 -sVa -p402 -V2008 -p403 -sVc -p404 -V5 -p405 -sVmisc_u -p406 -g16 -sVf -p407 -V3 -p408 -sVmrt -p409 -V60 -p410 -sVm -p411 -Vnone -p412 -sVm1ch -p413 -g376 -sVs -p414 -VOn -p415 +p48 sVmv -p416 -g383 +p49 +V0 +p50 +sVs +p51 +VOn +p52 +sVr +p53 +V0-100000 +p54 sVt -p417 +p55 Vfloatbs -p418 -ssV4-3 -p419 -(dp420 -g378 -V0-10000 -p421 -sVah -p422 -g16 +p56 +sVvm +p57 +NssV4-3 +p58 +(dp59 +Vah +p60 +g14 sVbytary -p423 +p61 NsVal -p424 -g383 +p62 +V0 +p63 sVvn -p425 +p64 VConductivity -p426 +p65 sVct -p427 +p66 Vnumber -p428 +p67 sVle -p429 +p68 V32 -p430 +p69 sVgrp -p431 +p70 V600 -p432 +p71 sVla -p433 +p72 Fnan sVchn -p434 +p73 Vconductivity -p435 +p74 sVun -p436 -g396 +p75 +V1 +p76 sVdn -p437 +p77 Vpromagmbs -p438 -sVvm -p439 -NsVlrt -p440 -F1515775621.2621409 +p78 sVda -p441 -g369 -sg402 +p79 +V2 +p80 +sVlrt +p81 +F1515775621.2621409 +sVa +p82 V2012 -p442 -sg404 +p83 +sVc +p84 V0.5 -p443 +p85 sVmisc_u -p444 -g16 -sg407 -g408 +p86 +g14 +sVf +p87 +V3 +p88 sVmrt -p445 +p89 V60 -p446 -sg411 +p90 +sVm +p91 Vnone -p447 +p92 sVm1ch -p448 -g419 -sg414 -VOn -p449 +p93 +V4-3 +p94 sVmv -p450 -g383 -sg417 +p95 +V0 +p96 +sVs +p97 +VOn +p98 +sVr +p99 +V0-10000 +p100 +sVt +p101 Vfloatbs -p451 -ssV4-4 -p452 -(dp453 -g378 -V0-10000000 -p454 -sVah -p455 -g16 +p102 +sVvm +p103 +NssV4-4 +p104 +(dp105 +Vah +p106 +g14 sVbytary -p456 +p107 NsVal -p457 -g383 +p108 +V0 +p109 sVvn -p458 +p110 VTotalizer 1 -p459 +p111 sVct -p460 +p112 Vnumber -p461 +p113 sVle -p462 +p114 V32 -p463 +p115 sVgrp -p464 +p116 V600 -p465 +p117 sVla -p466 +p118 F245249.88 sVchn -p467 +p119 Vtotalizer_1 -p468 +p120 sVun -p469 -g396 +p121 +V1 +p122 sVdn -p470 +p123 Vpromagmbs -p471 -sVvm -p472 -NsVlrt -p473 -F1515775638.257201 +p124 sVda -p474 -g369 -sg402 +p125 +V2 +p126 +sVlrt +p127 +F1515775638.257201 +sVa +p128 V2609 -p475 -sg404 +p129 +sVc +p130 V50.0 -p476 +p131 sVmisc_u -p477 -g16 -sg407 -g408 +p132 +g14 +sVf +p133 +V3 +p134 sVmrt -p478 +p135 V60 -p479 -sg411 +p136 +sVm +p137 Vnone -p480 +p138 sVm1ch -p481 -g452 -sg414 -VOn -p482 +p139 +V4-4 +p140 sVmv -p483 -g383 -sg417 -Vfloatbs -p484 -ssV4-5 -p485 -(dp486 -g378 +p141 +V0 +p142 +sVs +p143 +VOn +p144 +sVr +p145 V0-10000000 -p487 -sVah -p488 -g16 +p146 +sVt +p147 +Vfloatbs +p148 +sVvm +p149 +NssV4-5 +p150 +(dp151 +Vah +p152 +g14 sVbytary -p489 +p153 NsVal -p490 -g383 +p154 +V0 +p155 sVvn -p491 +p156 VTotalizer 2 -p492 +p157 sVct -p493 +p158 Vnumber -p494 +p159 sVle -p495 +p160 V32 -p496 +p161 sVgrp -p497 +p162 V600 -p498 +p163 sVla -p499 +p164 F265849.71999999997 sVchn -p500 +p165 Vtotalizer_2 -p501 +p166 sVun -p502 -g396 +p167 +V1 +p168 sVdn -p503 +p169 Vpromagmbs -p504 -sVvm -p505 -NsVlrt -p506 -F1515775574.6507481 +p170 sVda -p507 -g369 -sg402 +p171 +V2 +p172 +sVlrt +p173 +F1515775574.6507481 +sVa +p174 V2809 -p508 -sg404 +p175 +sVc +p176 V50 -p509 +p177 sVmisc_u -p510 -g16 -sg407 -g408 +p178 +g14 +sVf +p179 +V3 +p180 sVmrt -p511 +p181 V60 -p512 -sg411 +p182 +sVm +p183 Vnone -p513 +p184 sVm1ch -p514 -g485 -sg414 -VOn -p515 +p185 +V4-5 +p186 sVmv -p516 -g383 -sg417 +p187 +V0 +p188 +sVs +p189 +VOn +p190 +sVr +p191 +V0-10000000 +p192 +sVt +p193 Vfloatbs -p517 -ssV4-6 -p518 -(dp519 +p194 +sVvm +p195 +NssV4-6 +p196 +(dp197 Vah -p520 -g16 +p198 +g14 sVbytary -p521 +p199 NsVal -p522 -g383 +p200 +V0 +p201 sVvn -p523 +p202 VTotalizer 3 -p524 +p203 sVct -p525 +p204 Vnumber -p526 +p205 sVle -p527 +p206 V32 -p528 +p207 sVgrp -p529 +p208 V600 -p530 +p209 sVla -p531 +p210 I0 sVchn -p532 +p211 Vtotalizer_3 -p533 +p212 sVun -p534 -g396 +p213 +V1 +p214 sVdn -p535 +p215 Vpromagmbs -p536 +p216 sVda -p537 -g369 +p217 +V2 +p218 sVlrt -p538 +p219 F1515624472.5080973 -sg402 +sVr +p220 +V-10000000-10000000 +p221 +sVa +p222 V3009 -p539 -sg404 +p223 +sVc +p224 V50 -p540 +p225 sVmisc_u -p541 -g16 -sg407 -g408 +p226 +g14 +sVf +p227 +V3 +p228 sVmrt -p542 +p229 V60 -p543 -sg411 +p230 +sVm +p231 Vnone -p544 +p232 sVm1ch -p545 -g518 +p233 +V4-6 +p234 +sVs +p235 +VOn +p236 sVmv +p237 +V0 +p238 +sVt +p239 +Vfloatbs +p240 +sVvm +p241 +NssV4-7 +p242 +(dp243 +Vah +p244 +g14 +sVbytary +p245 +NsVal +p246 +g14 +sVvn +p247 +VVolume Flow Units +p248 +sVct +p249 +Vnumber +p250 +sVle +p251 +V16 +p252 +sVgrp +p253 +V86400 +p254 +sVla +p255 +I45 +sVchn +p256 +Vvolume_flow_units +p257 +sVun +p258 +V1 +p259 +sVdn +p260 +Vpromagmbs +p261 +sVda +p262 +V2 +p263 +sVlrt +p264 +F1515711271.343798 +sVa +p265 +V2102 +p266 +sVc +p267 +V0 +p268 +sVmisc_u +p269 +g14 +sVf +p270 +V3 +p271 +sVmrt +p272 +V60 +p273 +sVm +p274 +Vnone +p275 +sVm1ch +p276 +V4-7 +p277 +sVmv +p278 +V0 +p279 +sVs +p280 +VOn +p281 +sVr +p282 +V0-100 +p283 +sVt +p284 +Vint +p285 +sVvm +p286 +(dp287 +V24 +p288 +VMl/s +p289 +sV25 +p290 +VMl/min +p291 +sV26 +p292 +VMl/h +p293 +sV27 +p294 +VMl/d +p295 +sV20 +p296 +Vhl/s +p297 +sV21 +p298 +Vhl/min +p299 +sV22 +p300 +Vhl/h +p301 +sV23 +p302 +Vhl/d +p303 +sV0 +p304 +Vcm3/s +p305 +sV4 +p306 +Vdm3/s +p307 +sV8 +p308 +Vm3/s +p309 +sV59 +p310 +VBBL/d (US beer) +p311 +sV58 +p312 +VBBL/h (US beer) +p313 +sV55 +p314 +VBBL/d (US liq.) +p315 +sV54 +p316 +VBBL/h (US liq.) +p317 +sV57 +p318 +VBBL/min (US beer) +p319 +sV56 +p320 +VBBL/s (US beer) +p321 +sV51 +p322 +VMgal/d +p323 +sV50 +p324 +VMgal/h +p325 +sV53 +p326 +VBBL/min (US liq.) +p327 +sV52 +p328 +VBBL/s (US liq.) +p329 +sV88 +p330 +Vkgal/s (us) +p331 +sV89 +p332 +Vkgal/min (us) +p333 +sV82 +p334 +VBBL/h (imp oil) +p335 +sV83 +p336 +VBBL/d (imp oil) +p337 +sV80 +p338 +VBBL/s (imp oil) +p339 +sV81 +p340 +VBBL/min (imp oil) +p341 +sV86 +p342 +VUser vol / hour +p343 +sV87 +p344 +VUser vol / day +p345 +sV84 +p346 +VUser vol / s +p347 +sV85 +p348 +VUser vol / min +p349 +sV3 +p350 +Vcm3/d +p351 +sV7 +p352 +Vdm3/d +p353 +sV39 +p354 +Vft3/d +p355 +sV38 +p356 +Vft3/h +p357 +sV33 +p358 +Vaf/min +p359 +sV32 +p360 +Vaf/s +p361 +sV37 +p362 +Vft3/min +p363 +sV36 +p364 +Vft3/s +p365 +sV35 +p366 +Vaf/d +p367 +sV34 +p368 +Vaf/h +p369 +sV60 +p370 +VBBL/s (US oil) +p371 +sV61 +p372 +VBBL/min (US oil) +p373 +sV62 +p374 +VBBL/h (US oil) +p375 +sV63 +p376 +VBBL/d (US oil) +p377 +sV64 +p378 +VBBL/s (US tank) +p379 +sV65 +p380 +VBBL/min (US tank) +p381 +sV66 +p382 +VBBL/h (US tank) +p383 +sV67 +p384 +VBBL/d (US tank) +p385 +sV68 +p386 +Vgal/s (imp) +p387 +sV69 +p388 +Vgal/min (imp) +p389 +sV2 +p390 +Vcm3/h +p391 +sV6 +p392 +Vdm3/h +p393 +sV91 +p394 +Vkgal/d (us) +p395 +sV90 +p396 +Vkgal/h (us) +p397 +sV11 +p398 +Vm3/d +p399 +sV10 +p400 +Vm3/h +p401 +sV13 +p402 +VmL/min +p403 +sV12 +p404 +VmL/s +p405 +sV15 +p406 +VmL/d +p407 +sV14 +p408 +VmL/h +p409 +sV17 +p410 +Vl/min +p411 +sV16 +p412 +Vl/s +p413 +sV19 +p414 +Vl/d +p415 +sV18 +p416 +Vl/h +p417 +sV48 +p418 +VMgal/s +p419 +sV49 +p420 +VMgal/min +p421 +sV46 +p422 +Vgal/h +p423 +sV47 +p424 +Vgal/d +p425 +sV44 +p426 +Vgal/s +p427 +sV45 +p428 +Vgal/min +p429 +sV42 +p430 +Vfl oz/h +p431 +sV43 +p432 +Vfl oz/d +p433 +sV40 +p434 +Vfl oz/s +p435 +sV41 +p436 +Vfl oz/min +p437 +sV1 +p438 +Vcm3/min +p439 +sV5 +p440 +Vdm3/min +p441 +sV9 +p442 +Vm3/min +p443 +sV77 +p444 +VBBL/min (imp beer) +p445 +sV76 +p446 +VBBL/s (imp beer) +p447 +sV75 +p448 +VMgal/d (imp) +p449 +sV74 +p450 +VMgal/h (imp) +p451 +sV73 +p452 +VMgal/min (imp) +p453 +sV72 +p454 +VMgal/s (imp) +p455 +sV71 +p456 +Vgal/d (imp) +p457 +sV70 +p458 +Vgal/h (imp) +p459 +sV79 +p460 +VBBL/d (imp beer) +p461 +sV78 +p462 +VBBL/h (imp beer) +p463 +sssV4-8 +p464 +(dp465 +Vr +p466 +V0-22 +p467 +sVah +p468 +g14 +sVbytary +p469 +NsVal +p470 +g14 +sVvn +p471 +VVolume Units +p472 +sVct +p473 +Vnumber +p474 +sVle +p475 +V16 +p476 +sVgrp +p477 +V86400 +p478 +sVla +p479 +I11 +sVchn +p480 +g14 +sVun +p481 +g14 +sVdn +p482 +VM1 +p483 +sVvm +p484 +(dp485 +V20 +p486 +VBBL (imp oil) +p487 +sV21 +p488 +VUser vol. +p489 +sV22 +p490 +Vkgal (us) +p491 +sV1 +p492 +Vdm3 +p493 +sV0 +p494 +Vcm3 +p495 +sV3 +p496 +Vml +p497 +sV2 +p498 +Vm3 +p499 +sV5 +p500 +Vhl +p501 +sV4 +p502 +Vl +p503 +sV6 +p504 +VMl Mega +p505 +sV9 +p506 +Vft3 +p507 +sV8 +p508 +Vaf +p509 +sV11 +p510 +Vgal (us) +p511 +sV10 +p512 +Vfl oz (us) +p513 +sV13 +p514 +VBBL (US liq) +p515 +sV12 +p516 +VMgal (us) +p517 +sV15 +p518 +VBBL (US oil) +p519 +sV14 +p520 +VBBL (US beer) +p521 +sV17 +p522 +Vgal (imp) +p523 +sV16 +p524 +VBBL (US tank) +p525 +sV19 +p526 +VBBL (imp beer) +p527 +sV18 +p528 +VMgal (imp) +p529 +ssVlrt +p530 +F1515711271.8358025 +sVda +p531 +V2 +p532 +sVa +p533 +V2103 +p534 +sVc +p535 +V0 +p536 +sVmisc_u +p537 +g14 +sVf +p538 +V3 +p539 +sVmrt +p540 +V60 +p541 +sVm +p542 +Vnone +p543 +sVm1ch +p544 +V4-8 +p545 +sVs p546 -g383 -sg414 VOn p547 -sg378 -V-10000000-10000000 +sVmv p548 -sg417 -Vfloatbs +V0 p549 -sVvm +sVt p550 -NssV4-7 +Vint p551 -(dp552 -g378 -V0-100 -p553 -sVah +ssV4-9 +p552 +(dp553 +Vah p554 -g16 +g14 sVbytary p555 NsVal p556 -g16 +g14 sVvn p557 -VVolume Flow Units +VConductivity Unit p558 sVct p559 @@ -1378,1208 +1149,712 @@ V86400 p564 sVla p565 -I45 -sVchn -p566 -Vvolume_flow_units -p567 -sVun -p568 -g396 -sVdn -p569 -Vpromagmbs -p570 -sVvm -p571 -(dp572 -V24 -p573 -VMl/s -p574 -sV25 -p575 -VMl/min -p576 -sV26 -p577 -VMl/h -p578 -sV27 -p579 -VMl/d -p580 -sV20 -p581 -Vhl/s -p582 -sV21 -p583 -Vhl/min -p584 -sV22 -p585 -Vhl/h -p586 -sV23 -p587 -Vhl/d -p588 -sg383 -Vcm3/s -p589 -sV4 -p590 -Vdm3/s -p591 -sV8 -p592 -Vm3/s -p593 -sV59 -p594 -VBBL/d (US beer) -p595 -sV58 -p596 -VBBL/h (US beer) -p597 -sV55 -p598 -VBBL/d (US liq.) -p599 -sV54 -p600 -VBBL/h (US liq.) -p601 -sV57 -p602 -VBBL/min (US beer) -p603 -sV56 -p604 -VBBL/s (US beer) -p605 -sV51 -p606 -VMgal/d -p607 -sV50 -p608 -VMgal/h -p609 -sV53 -p610 -VBBL/min (US liq.) -p611 -sV52 -p612 -VBBL/s (US liq.) -p613 -sV88 -p614 -Vkgal/s (us) -p615 -sV89 -p616 -Vkgal/min (us) -p617 -sV82 -p618 -VBBL/h (imp oil) -p619 -sV83 -p620 -VBBL/d (imp oil) -p621 -sV80 -p622 -VBBL/s (imp oil) -p623 -sV81 -p624 -VBBL/min (imp oil) -p625 -sV86 -p626 -VUser vol / hour -p627 -sV87 -p628 -VUser vol / day -p629 -sV84 -p630 -VUser vol / s -p631 -sV85 -p632 -VUser vol / min -p633 -sg408 -Vcm3/d -p634 -sV7 -p635 -Vdm3/d -p636 -sV39 -p637 -Vft3/d -p638 -sV38 -p639 -Vft3/h -p640 -sV33 -p641 -Vaf/min -p642 -sV32 -p643 -Vaf/s -p644 -sV37 -p645 -Vft3/min -p646 -sV36 -p647 -Vft3/s -p648 -sV35 -p649 -Vaf/d -p650 -sV34 -p651 -Vaf/h -p652 -sV60 -p653 -VBBL/s (US oil) -p654 -sV61 -p655 -VBBL/min (US oil) -p656 -sV62 -p657 -VBBL/h (US oil) -p658 -sV63 -p659 -VBBL/d (US oil) -p660 -sV64 -p661 -VBBL/s (US tank) -p662 -sV65 -p663 -VBBL/min (US tank) -p664 -sV66 -p665 -VBBL/h (US tank) -p666 -sV67 -p667 -VBBL/d (US tank) -p668 -sV68 -p669 -Vgal/s (imp) -p670 -sV69 -p671 -Vgal/min (imp) -p672 -sg369 -Vcm3/h -p673 -sV6 -p674 -Vdm3/h -p675 -sV91 -p676 -Vkgal/d (us) -p677 -sV90 -p678 -Vkgal/h (us) -p679 -sV11 -p680 -Vm3/d -p681 -sV10 -p682 -Vm3/h -p683 -sV13 -p684 -VmL/min -p685 -sV12 -p686 -VmL/s -p687 -sV15 -p688 -VmL/d -p689 -sV14 -p690 -VmL/h -p691 -sV17 -p692 -Vl/min -p693 -sV16 -p694 -Vl/s -p695 -sV19 -p696 -Vl/d -p697 -sV18 -p698 -Vl/h -p699 -sV48 -p700 -VMgal/s -p701 -sV49 -p702 -VMgal/min -p703 -sV46 -p704 -Vgal/h -p705 -sV47 -p706 -Vgal/d -p707 -sV44 -p708 -Vgal/s -p709 -sV45 -p710 -Vgal/min -p711 -sV42 -p712 -Vfl oz/h -p713 -sV43 -p714 -Vfl oz/d -p715 -sV40 -p716 -Vfl oz/s -p717 -sV41 -p718 -Vfl oz/min -p719 -sg396 -Vcm3/min -p720 -sg405 -Vdm3/min -p721 -sV9 -p722 -Vm3/min -p723 -sV77 -p724 -VBBL/min (imp beer) -p725 -sV76 -p726 -VBBL/s (imp beer) -p727 -sV75 -p728 -VMgal/d (imp) -p729 -sV74 -p730 -VMgal/h (imp) -p731 -sV73 -p732 -VMgal/min (imp) -p733 -sV72 -p734 -VMgal/s (imp) -p735 -sV71 -p736 -Vgal/d (imp) -p737 -sV70 -p738 -Vgal/h (imp) -p739 -sV79 -p740 -VBBL/d (imp beer) -p741 -sV78 -p742 -VBBL/h (imp beer) -p743 -ssVlrt -p744 -F1515711271.343798 -sVda -p745 -g369 -sg402 -V2102 -p746 -sg404 -g383 -sVmisc_u -p747 -g16 -sg407 -g408 -sVmrt -p748 -V60 -p749 -sg411 -Vnone -p750 -sVm1ch -p751 -g551 -sg414 -VOn -p752 -sVmv -p753 -g383 -sg417 -Vint -p754 -ssV4-8 -p755 -(dp756 -Vah -p757 -g16 -sVbytary -p758 -NsVal -p759 -g16 -sVvn -p760 -VVolume Units -p761 -sVct -p762 -Vnumber -p763 -sVle -p764 -V16 -p765 -sVgrp -p766 -V86400 -p767 -sVla -p768 -I11 -sVchn -p769 -g16 -sVun -p770 -g16 -sVdn -p771 -VM1 -p772 -sVvm -p773 -(dp774 -V20 -p775 -VBBL (imp oil) -p776 -sV21 -p777 -VUser vol. -p778 -sV22 -p779 -Vkgal (us) -p780 -sg396 -Vdm3 -p781 -sg383 -Vcm3 -p782 -sg408 -Vml -p783 -sg369 -Vm3 -p784 -sg405 -Vhl -p785 -sg590 -Vl -p786 -sg674 -VMl Mega -p787 -sg722 -Vft3 -p788 -sg592 -Vaf -p789 -sV11 -p790 -Vgal (us) -p791 -sV10 -p792 -Vfl oz (us) -p793 -sV13 -p794 -VBBL (US liq) -p795 -sV12 -p796 -VMgal (us) -p797 -sV15 -p798 -VBBL (US oil) -p799 -sV14 -p800 -VBBL (US beer) -p801 -sV17 -p802 -Vgal (imp) -p803 -sV16 -p804 -VBBL (US tank) -p805 -sV19 -p806 -VBBL (imp beer) -p807 -sV18 -p808 -VMgal (imp) -p809 -ssVlrt -p810 -F1515711271.8358022 -sVda -p811 -g369 -sg402 -V2103 -p812 -sg404 -g383 -sVmisc_u -p813 -g16 -sg407 -g408 -sVmrt -p814 -V60 -p815 -sg411 -Vnone -p816 -sVm1ch -p817 -g755 -sVmv -p818 -g383 -sg414 -VOn -p819 -sg378 -V0-22 -p820 -sg417 -Vint -p821 -ssV4-9 -p822 -(dp823 -Val -p824 -g16 -sVah -p825 -g16 -sVbytary -p826 -NsVvm -p827 -NsVvn -p828 -VConductivity Unit -p829 -sVct -p830 -Vnumber -p831 -sVle -p832 -V16 -p833 -sVgrp -p834 -V86400 -p835 -sVla -p836 I8 sVchn -p837 -g16 +p566 +g14 sVun -p838 -g16 +p567 +g14 sVdn -p839 +p568 VM1 -p840 -sVda -p841 -g369 -sVlrt -p842 +p569 +sVvm +p570 +NsVlrt +p571 F1515711272.3275089 -sg378 -V0-10 -p843 -sg402 +sVda +p572 +V2 +p573 +sVa +p574 V2120 -p844 -sg404 -g383 +p575 +sVc +p576 +V0 +p577 sVmisc_u -p845 -g16 -sg407 -g408 +p578 +g14 +sVf +p579 +V3 +p580 sVmrt -p846 +p581 V60 -p847 -sg411 +p582 +sVm +p583 Vnone -p848 -sS'm1ch' -p849 -g822 -sg414 -VOn -p850 +p584 +sVm1ch +p585 +V4-9 +p586 sVmv -p851 -g383 -sg417 +p587 +V0 +p588 +sVs +p589 +VOn +p590 +sVr +p591 +V0-10 +p592 +sVt +p593 Vint -p852 +p594 ssV4-12 -p853 -(dp854 -Vah -p855 -g16 +p595 +(dp596 +Vr +p597 +V0-56 +p598 +sVah +p599 +g14 sVbytary -p856 +p600 NsVal -p857 -g16 +p601 +g14 sVvn -p858 +p602 VTotalizer 1 Units -p859 +p603 sVct -p860 +p604 Vnumber -p861 +p605 sVle -p862 +p606 V16 -p863 +p607 sVgrp -p864 +p608 V86400 -p865 +p609 sVla -p866 +p610 I11 sVchn -p867 +p611 Vtotalizer_1_units -p868 +p612 sVun -p869 -g396 +p613 +V1 +p614 sVdn -p870 +p615 Vpromagmbs -p871 +p616 sVvm -p872 -(dp873 +p617 +(dp618 V20 -p874 +p619 VBBL (imp oil) -p875 +p620 sV21 -p876 +p621 VUser vol. -p877 +p622 sV22 -p878 +p623 VkGal (us) -p879 -sg396 +p624 +sV1 +p625 Vdm3 -p880 -sg383 +p626 +sV0 +p627 Vcm3 -p881 -sg408 +p628 +sV3 +p629 Vml -p882 -sg369 +p630 +sV2 +p631 Vm3 -p883 -sg405 +p632 +sV5 +p633 Vhl -p884 -sg590 -g786 -sg674 +p634 +sV4 +p635 +Vl +p636 +sV6 +p637 VMl Mega -p885 -sg722 +p638 +sV9 +p639 Vft3 -p886 -sg592 +p640 +sV8 +p641 Vaf -p887 +p642 sV11 -p888 +p643 Vgal (us) -p889 +p644 sV10 -p890 +p645 Vfl oz (us) -p891 +p646 sV13 -p892 +p647 VBBL (US liq) -p893 +p648 sV12 -p894 +p649 VMgal (us) -p895 +p650 sV15 -p896 +p651 VBBL (US oil) -p897 +p652 sV14 -p898 +p653 VBBL (US beer) -p899 +p654 sV17 -p900 +p655 Vgal (imp) -p901 +p656 sV16 -p902 +p657 VBBL (US tank) -p903 +p658 sV19 -p904 +p659 VBBL (imp beer) -p905 +p660 sV18 -p906 +p661 VMgal (imp) -p907 +p662 sV56 -p908 +p663 VUser mass -p909 +p664 sV51 -p910 +p665 Vkg -p911 +p666 sV50 -p912 +p667 Vg -p913 +p668 sV53 -p914 +p669 Voz -p915 +p670 sV52 -p916 -g417 +p671 +Vt +p672 sV55 -p917 +p673 VSTon -p918 +p674 sV54 -p919 +p675 Vlb -p920 +p676 ssVlrt -p921 +p677 F1515711272.82556 sVda -p922 -g369 -sg402 +p678 +V2 +p679 +sVa +p680 V4603 -p923 -sg404 -g383 +p681 +sVc +p682 +V0 +p683 sVmisc_u -p924 -g16 -sg407 -g408 +p684 +g14 +sVf +p685 +V3 +p686 sVmrt -p925 +p687 V60 -p926 -sg411 +p688 +sVm +p689 Vnone -p927 +p690 sVm1ch -p928 -g853 -sVmv -p929 -g383 -sg414 +p691 +V4-12 +p692 +sVs +p693 VOn -p930 -sg378 -V0-56 -p931 -sg417 +p694 +sVmv +p695 +V0 +p696 +sVt +p697 Vint -p932 +p698 ssV4-13 -p933 -(dp934 -Val -p935 -g16 -sVah -p936 -g16 +p699 +(dp700 +Vah +p701 +g14 sVbytary -p937 -NsVvm -p938 -(dp939 -V20 -p940 -VBBL (imp oil) -p941 -sV21 -p942 -VUser vol. -p943 -sV22 -p944 -VkGal (us) -p945 -sg396 -Vdm3 -p946 -sg383 -Vcm3 -p947 -sg408 -Vml -p948 -sg369 -Vm3 -p949 -sg405 -Vhl -p950 -sg590 -g786 -sg674 -VMl Mega -p951 -sg722 -Vft3 -p952 -sg592 -Vaf -p953 -sV11 -p954 -Vgal (us) -p955 -sV10 -p956 -Vfl oz (us) -p957 -sV13 -p958 -VBBL (US liq) -p959 -sV12 -p960 -VMgal (us) -p961 -sV15 -p962 -VBBL (US oil) -p963 -sV14 -p964 -VBBL (US beer) -p965 -sV17 -p966 -Vgal (imp) -p967 -sV16 -p968 -VBBL (US tank) -p969 -sV19 -p970 -VBBL (imp beer) -p971 -sV18 -p972 -VMgal (imp) -p973 -sV56 -p974 -VUser mass -p975 -sV51 -p976 -Vkg -p977 -sV50 -p978 -g913 -sV53 -p979 -Voz -p980 -sV52 -p981 -g417 -sV55 -p982 -VSTon -p983 -sV54 -p984 -Vlb -p985 -ssVvn -p986 +p702 +NsVal +p703 +g14 +sVvn +p704 VTotalizer 2 Units -p987 +p705 sVct -p988 +p706 Vnumber -p989 +p707 sVle -p990 +p708 V16 -p991 +p709 sVgrp -p992 +p710 V86400 -p993 +p711 sVla -p994 +p712 I11 sVchn -p995 +p713 Vtotalizer_2_units -p996 +p714 sVun -p997 -g396 +p715 +V1 +p716 sVdn -p998 +p717 Vpromagmbs -p999 -sVda -p1000 -g369 -sVlrt -p1001 -F1515711273.323234 -sg378 -V0-56 -p1002 -sg402 -V4604 -p1003 -sg404 -g383 -sVmisc_u -p1004 -g16 -sg407 -g408 -sVmrt -p1005 -V60 -p1006 -sg411 -Vnone -p1007 -sVm1ch -p1008 -g933 -sg414 -VOn -p1009 -sVmv -p1010 -g383 -sg417 -Vint -p1011 -ssV4-14 -p1012 -(dp1013 -Val -p1014 -g16 -sVah -p1015 -g16 -sVbytary -p1016 -NsVvm -p1017 -(dp1018 +p718 +sVvm +p719 +(dp720 V20 -p1019 +p721 VBBL (imp oil) -p1020 +p722 sV21 -p1021 +p723 VUser vol. -p1022 +p724 sV22 -p1023 +p725 VkGal (us) -p1024 -sg396 +p726 +sV1 +p727 Vdm3 -p1025 -sg383 +p728 +sV0 +p729 Vcm3 -p1026 -sg408 +p730 +sV3 +p731 Vml -p1027 -sg369 +p732 +sV2 +p733 Vm3 -p1028 -sg405 +p734 +sV5 +p735 Vhl -p1029 -sg590 -g786 -sg674 +p736 +sV4 +p737 +Vl +p738 +sV6 +p739 VMl Mega -p1030 -sg722 +p740 +sV9 +p741 Vft3 -p1031 -sg592 +p742 +sV8 +p743 Vaf -p1032 +p744 sV11 -p1033 +p745 Vgal (us) -p1034 +p746 sV10 -p1035 +p747 Vfl oz (us) -p1036 +p748 sV13 -p1037 +p749 VBBL (US liq) -p1038 +p750 sV12 -p1039 +p751 VMgal (us) -p1040 +p752 sV15 -p1041 +p753 VBBL (US oil) -p1042 +p754 sV14 -p1043 +p755 VBBL (US beer) -p1044 +p756 sV17 -p1045 +p757 Vgal (imp) -p1046 +p758 sV16 -p1047 +p759 VBBL (US tank) -p1048 +p760 sV19 -p1049 +p761 VBBL (imp beer) -p1050 +p762 sV18 -p1051 +p763 VMgal (imp) -p1052 +p764 sV56 -p1053 +p765 VUser mass -p1054 +p766 sV51 -p1055 +p767 Vkg -p1056 +p768 sV50 -p1057 -g913 +p769 +Vg +p770 sV53 -p1058 +p771 Voz -p1059 +p772 sV52 -p1060 -g417 +p773 +Vt +p774 sV55 -p1061 +p775 VSTon -p1062 +p776 sV54 -p1063 +p777 Vlb -p1064 -ssVvn -p1065 +p778 +ssVlrt +p779 +F1515711273.323234 +sVda +p780 +V2 +p781 +sVa +p782 +V4604 +p783 +sVc +p784 +V0 +p785 +sVmisc_u +p786 +g14 +sVf +p787 +V3 +p788 +sVmrt +p789 +V60 +p790 +sVm +p791 +Vnone +p792 +sVm1ch +p793 +V4-13 +p794 +sVmv +p795 +V0 +p796 +sVs +p797 +VOn +p798 +sVr +p799 +V0-56 +p800 +sVt +p801 +Vint +p802 +ssV4-14 +p803 +(dp804 +Vah +p805 +g14 +sVbytary +p806 +NsVal +p807 +g14 +sVvn +p808 VTotalizer 3 Units -p1066 +p809 sVct -p1067 +p810 Vnumber -p1068 +p811 sVle -p1069 +p812 V16 -p1070 +p813 sVgrp -p1071 +p814 V86400 -p1072 +p815 sVla -p1073 +p816 I11 sVchn -p1074 +p817 Vtotalizer_3_units -p1075 +p818 sVun -p1076 -g396 +p819 +V1 +p820 sVdn -p1077 +p821 Vpromagmbs -p1078 -sVda -p1079 -g369 -sVlrt -p1080 +p822 +sVvm +p823 +(dp824 +V20 +p825 +VBBL (imp oil) +p826 +sV21 +p827 +VUser vol. +p828 +sV22 +p829 +VkGal (us) +p830 +sV1 +p831 +Vdm3 +p832 +sV0 +p833 +Vcm3 +p834 +sV3 +p835 +Vml +p836 +sV2 +p837 +Vm3 +p838 +sV5 +p839 +Vhl +p840 +sV4 +p841 +Vl +p842 +sV6 +p843 +VMl Mega +p844 +sV9 +p845 +Vft3 +p846 +sV8 +p847 +Vaf +p848 +sV11 +p849 +Vgal (us) +p850 +sV10 +p851 +Vfl oz (us) +p852 +sV13 +p853 +VBBL (US liq) +p854 +sV12 +p855 +VMgal (us) +p856 +sV15 +p857 +VBBL (US oil) +p858 +sV14 +p859 +VBBL (US beer) +p860 +sV17 +p861 +Vgal (imp) +p862 +sV16 +p863 +VBBL (US tank) +p864 +sV19 +p865 +VBBL (imp beer) +p866 +sV18 +p867 +VMgal (imp) +p868 +sV56 +p869 +VUser mass +p870 +sV51 +p871 +Vkg +p872 +sV50 +p873 +Vg +p874 +sV53 +p875 +Voz +p876 +sV52 +p877 +Vt +p878 +sV55 +p879 +VSTon +p880 +sV54 +p881 +Vlb +p882 +ssVlrt +p883 F1515711273.829602 -sg378 -V0-56 -p1081 -sg402 +sVda +p884 +V2 +p885 +sVa +p886 V4605 -p1082 -sg404 -g383 +p887 +sVc +p888 +V0 +p889 sVmisc_u -p1083 -g16 -sg407 -g408 +p890 +g14 +sVf +p891 +V3 +p892 sVmrt -p1084 +p893 V60 -p1085 -sg411 +p894 +sVm +p895 Vnone -p1086 +p896 sVm1ch -p1087 -g1012 -sg414 -VOn -p1088 +p897 +V4-14 +p898 sVmv -p1089 -g383 -sg417 +p899 +V0 +p900 +sVs +p901 +VOn +p902 +sVr +p903 +V0-56 +p904 +sVt +p905 Vint -p1090 -ssssg365 +p906 +ssssVf +p907 VOff -p1091 -sg367 +p908 +sVp +p909 VNone -p1092 -sg368 -g396 +p910 +sVs +p911 +V2 +p912 ss. \ No newline at end of file diff --git a/tenflowmeterskid/Tags.py b/tenflowmeterskid/Tags.py index b0eb12d..73a5a0d 100644 --- a/tenflowmeterskid/Tags.py +++ b/tenflowmeterskid/Tags.py @@ -2,66 +2,81 @@ from Channel import PLCChannel, ModbusChannel from tenflowmeterskid import PLC_IP_ADDRESS tags = [ - PLCChannel(PLC_IP_ADDRESS, "fm1_flowrate","Val_FM1_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm2_flowrate","Val_FM2_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm3_flowrate","Val_FM3_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm4_flowrate","Val_FM4_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm5_flowrate","Val_FM5_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm6_flowrate","Val_FM6_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm7_flowrate","Val_FM7_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm8_flowrate","Val_FM8_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm9_flowrate","Val_FM9_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm10_flowrate","Val_FM10_FR","REAL", 250, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm1_lifetime","Val_FM1_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm2_lifetime","Val_FM2_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm3_lifetime","Val_FM3_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm4_lifetime","Val_FM4_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm5_lifetime","Val_FM5_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm6_lifetime","Val_FM6_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm7_lifetime","Val_FM7_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm8_lifetime","Val_FM8_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm9_lifetime","Val_FM9_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm10_lifetime","Val_FM10_T1","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm1_month","Val_Flowmeter1MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm2_month","Val_Flowmeter2MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm3_month","Val_Flowmeter3MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm4_month","Val_Flowmeter4MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm5_month","Val_Flowmeter5MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm6_month","Val_Flowmeter6MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm7_month","Val_Flowmeter7MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm8_month","Val_Flowmeter8MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm9_month","Val_Flowmeter9MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm10_month","Val_Flowmeter10MonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm1_lastmonth","Val_Flowmeter1LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm2_lastmonth","Val_Flowmeter2LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm3_lastmonth","Val_Flowmeter3LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm4_lastmonth","Val_Flowmeter4LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm5_lastmonth","Val_Flowmeter5LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm6_lastmonth","Val_Flowmeter6LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm7_lastmonth","Val_Flowmeter7LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm8_lastmonth","Val_Flowmeter8LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm9_lastmonth","Val_Flowmeter9LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm10_lastmonth","Val_Flowmeter10LastMonthTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm1_yesterdays","Val_Flowmeter1YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm2_yesterdays","Val_Flowmeter2YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm3_yesterdays","Val_Flowmeter3YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm4_yesterdays","Val_Flowmeter4YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm5_yesterdays","Val_Flowmeter5YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm6_yesterdays","Val_Flowmeter6YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm7_yesterdays","Val_Flowmeter7YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm8_yesterdays","Val_Flowmeter8YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm9_yesterdays","Val_Flowmeter9YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm10_yesterdays","Val_Flowmeter10YesterdaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm1_todays","Val_Flowmeter1TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm2_todays","Val_Flowmeter2TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm3_todays","Val_Flowmeter3TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm4_todays","Val_Flowmeter4TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm5_todays","Val_Flowmeter5TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm6_todays","Val_Flowmeter6TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm7_todays","Val_Flowmeter7TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm8_todays","Val_Flowmeter8TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm9_todays","Val_Flowmeter9TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "fm10_todays","Val_Flowmeter10TodaysTotal","REAL", 100, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm1_flowrate","Val_FM1_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm2_flowrate","Val_FM2_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm3_flowrate","Val_FM3_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm4_flowrate","Val_FM4_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm5_flowrate","Val_FM5_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm6_flowrate","Val_FM6_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm7_flowrate","Val_FM7_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm8_flowrate","Val_FM8_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm9_flowrate","Val_FM9_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm10_flowrate","Val_FM10_FR","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_in_flowrate", "Val_FRTotalIn", "REAL",1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_out_flowrate", "Val_FRTotalOut", "REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm1_lifetime","Val_FM1_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm2_lifetime","Val_FM2_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm3_lifetime","Val_FM3_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm4_lifetime","Val_FM4_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm5_lifetime","Val_FM5_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm6_lifetime","Val_FM6_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm7_lifetime","Val_FM7_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm8_lifetime","Val_FM8_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm9_lifetime","Val_FM9_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm10_lifetime","Val_FM10_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "forward_out_lifetime","Val_Out_T1","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "net_out_lifetime","Val_Out_T2","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "reverse_out_lifetime","Val_Out_T3","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_in_lifetime", "Val_T1TotalIn", "REAL",1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_out_lifetime", "Val_T1TotalOut", "REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm1_month","Val_Flowmeter1MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm2_month","Val_Flowmeter2MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm3_month","Val_Flowmeter3MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm4_month","Val_Flowmeter4MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm5_month","Val_Flowmeter5MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm6_month","Val_Flowmeter6MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm7_month","Val_Flowmeter7MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm8_month","Val_Flowmeter8MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm9_month","Val_Flowmeter9MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm10_month","Val_Flowmeter10MonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_in_month", "Val_MonthTotalIn", "REAL",1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_out_month", "Val_MonthTotalOut", "REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm1_lastmonth","Val_Flowmeter1LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm2_lastmonth","Val_Flowmeter2LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm3_lastmonth","Val_Flowmeter3LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm4_lastmonth","Val_Flowmeter4LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm5_lastmonth","Val_Flowmeter5LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm6_lastmonth","Val_Flowmeter6LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm7_lastmonth","Val_Flowmeter7LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm8_lastmonth","Val_Flowmeter8LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm9_lastmonth","Val_Flowmeter9LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm10_lastmonth","Val_Flowmeter10LastMonthTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_in_lastmonth", "Val_LastMonthTotalIn", "REAL",1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_out_lastmonth", "Val_LastMonthTotalOut", "REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm1_yesterdays","Val_Flowmeter1YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm2_yesterdays","Val_Flowmeter2YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm3_yesterdays","Val_Flowmeter3YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm4_yesterdays","Val_Flowmeter4YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm5_yesterdays","Val_Flowmeter5YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm6_yesterdays","Val_Flowmeter6YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm7_yesterdays","Val_Flowmeter7YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm8_yesterdays","Val_Flowmeter8YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm9_yesterdays","Val_Flowmeter9YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm10_yesterdays","Val_Flowmeter10YesterdaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_in_yesterday", "Val_YesterdaysTotalIn", "REAL",1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_out_yesterday", "Val_YesterdaysTotalOut", "REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm1_todays","Val_Flowmeter1TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm2_todays","Val_Flowmeter2TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm3_todays","Val_Flowmeter3TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm4_todays","Val_Flowmeter4TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm5_todays","Val_Flowmeter5TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm6_todays","Val_Flowmeter6TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm7_todays","Val_Flowmeter7TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm8_todays","Val_Flowmeter8TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm9_todays","Val_Flowmeter9TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "fm10_todays","Val_Flowmeter10TodaysTotal","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_in_today", "Val_TodaysTotalIn", "REAL",1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "total_out_today", "Val_TodaysTotalOut", "REAL", 1000000000, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_1_raw_min","pond1scaling.rawmin","REAL", 5, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_1_raw_max","pond1scaling.rawmax","REAL", 5, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_1_eu_min","pond1scaling.eumin","REAL", 5, 3600, plc_type="Micro800"), @@ -74,11 +89,11 @@ tags = [ PLCChannel(PLC_IP_ADDRESS, "pond_2_offset","pond2offset","REAL", 5, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_1_height","pond1Height","REAL", 5, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_2_height","pond2height","REAL", 5, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "pond_1_volume","pond1volume","REAL", 100000, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "pond_2_volume","pond2volume","REAL", 100000, 3600, plc_type="Micro800"), - PLCChannel(PLC_IP_ADDRESS, "pond_sum_volume","pondVolumeTotal","REAL", 300000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "pond_1_volume","pond1volume","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "pond_2_volume","pond2volume","REAL", 1000000000, 3600, plc_type="Micro800"), + PLCChannel(PLC_IP_ADDRESS, "pond_sum_volume","pondVolumeTotal","REAL", 3000000000, 3600, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_1_high_spt","SPT_Pond_1_High_Level","REAL", 1, 86400, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_2_high_spt","SPT_Pond_2_High_Level","REAL", 1, 86400, plc_type="Micro800"), PLCChannel(PLC_IP_ADDRESS, "pond_1_alarm","Pond1HiAlarm","BOOL", 0, 3600, plc_type="Micro800", map_={0: "Good", 1: "High", None: "Error"}), PLCChannel(PLC_IP_ADDRESS, "pond_2_alarm","Pond2HiAlarm","BOOL", 0, 3600, plc_type="Micro800", map_={0: "Good", 1: "High", None: "Error"}) -] \ No newline at end of file +] diff --git a/tenflowmeterskid/tenflowmeterskid.py b/tenflowmeterskid/tenflowmeterskid.py index 9ea3075..22fbfd3 100644 --- a/tenflowmeterskid/tenflowmeterskid.py +++ b/tenflowmeterskid/tenflowmeterskid.py @@ -8,7 +8,7 @@ import os from device_base import deviceBase from Channel import PLCChannel, ModbusChannel,read_tag, write_tag, TAG_DATAERROR_SLEEPTIME import persistence -from utilities import get_public_ip_address +from utilities import get_public_ip_address, get_private_ip_address from file_logger import filelogger as log PLC_IP_ADDRESS = "192.168.1.12" from Tags import tags @@ -26,6 +26,11 @@ CHANNELS = tags # PERSISTENCE FILE PERSIST = persistence.load() +if not PERSIST: + PERSIST = { + "ignore_list": [] + } + persistence.store(PERSIST) CALIBRATION_TABLES = [[],[], [], ] @@ -45,6 +50,7 @@ class start(threading.Thread, deviceBase): self.finished = threading.Event() self.force_send = False self.public_ip_address = "" + self.private_ip_address = "" self.public_ip_address_last_checked = 0 threading.Thread.start(self) @@ -76,7 +82,10 @@ class start(threading.Thread, deviceBase): for chan in CHANNELS: val = chan.read() if chan.check(val, self.force_send): - self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'tenflowmeterskid') + if chan.mesh_name in PERSIST["ignore_list"]: + self.sendtodbDev(1, chan.mesh_name, None, 0, 'tenflowmeterskid') + else: + self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'tenflowmeterskid') #time.sleep(TAG_DATAERROR_SLEEPTIME) # sleep to allow Micro800 to handle ENET requests for pond_index in range(1, 3): @@ -100,11 +109,21 @@ class start(threading.Thread, deviceBase): """Check the public IP address and send to Meshify if changed.""" self.public_ip_address_last_checked = time.time() test_public_ip = get_public_ip_address() - if not test_public_ip == self.public_ip_address: + test_public_ip = test_public_ip + test_private_ip = get_private_ip_address() + if not test_public_ip == self.public_ip_address and not test_public_ip == "0.0.0.0": self.sendtodbDev(1, 'public_ip_address', test_public_ip, 0, 'tenflowmeterskid') self.public_ip_address = test_public_ip + if not test_private_ip == self.private_ip_address: + self.sendtodbDev(1, 'private_ip_address', test_private_ip, 0, 'tenflowmeterskid') + self.private_ip_address = test_private_ip hostname = "google.com" - response = os.system("ping -c 1 " + hostname) + response = 1 + try: + response = os.system("ping -c 1 " + hostname + " > /dev/null 2>&1") + except Exception as e: + print("Something went wrong in ping: {}".format(e)) + #and then check the response... if response == 0: @@ -297,3 +316,15 @@ class start(threading.Thread, deviceBase): if write_res is None: write_res = "Error writing to PLC..." return write_res + + def tenflowmeterskid_ignorechannel(self, name, value): + if value not in PERSIST["ignore_list"]: + PERSIST["ignore_list"].append(value) + persistence.store(PERSIST) + return True + + def tenflowmeterskid_observechannel(self, name, value): + if value in PERSIST["ignore_list"]: + PERSIST["ignore_list"].remove(value) + persistence.store(PERSIST) + return True \ No newline at end of file diff --git a/tenflowmeterskid/utilities.py b/tenflowmeterskid/utilities.py index 7e88d62..bd90c33 100644 --- a/tenflowmeterskid/utilities.py +++ b/tenflowmeterskid/utilities.py @@ -1,19 +1,31 @@ """Utility functions for the driver.""" import socket import struct +import urllib +import contextlib - -def get_public_ip_address(): - """Find the public IP Address of the host device.""" +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 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.connect(("8.8.8.8", 80)) - ip_address = sock.getsockname()[0] - sock.close() 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."""