Finalized with documentation
This commit is contained in:
@@ -42,6 +42,35 @@ def read_tag(addr, tag, plc_type="CLX"):
|
||||
return False
|
||||
|
||||
|
||||
def read_tag_group(addr, tag_list, plc_type="CLX"):
|
||||
"""Read a tag group from the PLC."""
|
||||
direct = plc_type.lower() == "micro800"
|
||||
read_values = []
|
||||
clx = ClxDriver()
|
||||
try:
|
||||
if clx.open(addr, direct_connection=direct):
|
||||
for i in range(0, len(tag_list)):
|
||||
try:
|
||||
val = clx.read_tag(tag_list[i])
|
||||
read_values.append(val)
|
||||
except DataError as err:
|
||||
read_values.append(None)
|
||||
time.sleep(TAG_DATAERROR_SLEEPTIME)
|
||||
log.error("Data Error during read_tag_group({}, {}): {}".format(addr, tag_list[i], err))
|
||||
else:
|
||||
log.error("Error opening {}".format(addr))
|
||||
except CommError:
|
||||
# err = c.get_status()
|
||||
clx.close()
|
||||
log.error("Could not connect during read_tag_group({})".format(addr))
|
||||
except AttributeError as err:
|
||||
clx.close()
|
||||
log.error("AttributeError during read_tag_group({}: \n{}".format(addr, err))
|
||||
clx.close()
|
||||
return read_values
|
||||
|
||||
|
||||
|
||||
def read_array(addr, tag, start, end, plc_type="CLX"):
|
||||
"""Read an array from the PLC."""
|
||||
direct = plc_type == "Micro800"
|
||||
@@ -70,11 +99,15 @@ def write_tag(addr, tag, val, plc_type="CLX"):
|
||||
"""Write a tag value to the PLC."""
|
||||
direct = plc_type == "Micro800"
|
||||
clx = ClxDriver()
|
||||
write_status = None
|
||||
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])
|
||||
if initial_val:
|
||||
write_status = clx.write_tag(tag, val, initial_val[1])
|
||||
else:
|
||||
log.error("Unable to get initial value in write_tag({}, {}, {}, {})".format(addr, tag, val, plc_type))
|
||||
return write_status
|
||||
except DataError as err:
|
||||
clx_err = clx.get_status()
|
||||
@@ -85,6 +118,7 @@ def write_tag(addr, tag, val, plc_type="CLX"):
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import time
|
||||
from random import randint
|
||||
|
||||
from device_base import deviceBase
|
||||
from channel import PLCChannel, read_tag, write_tag
|
||||
from channel import PLCChannel, read_tag, write_tag, read_tag_group
|
||||
from utilities import get_public_ip_address
|
||||
|
||||
from file_logger import filelogger as log
|
||||
@@ -70,6 +70,24 @@ CHANNELS = [
|
||||
PLCChannel(PLC_IP_ADDRESS, 'pond5volume', 'input5.pondVolume', 'REAL', 1000.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'pond6volume', 'input6.pondVolume', 'REAL', 1000.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'pond7volume', 'input7.pondVolume', 'REAL', 1000.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an0min', 'input0_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an1min', 'input1_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an2min', 'input2_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an3min', 'input3_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an4min', 'input4_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an5min', 'input5_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an6min', 'input6_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an7min', 'input7_cfg.scalingConfig.euMin', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an0max', 'input0_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an1max', 'input1_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an2max', 'input2_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an3max', 'input3_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an4max', 'input4_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an5max', 'input5_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an6max', 'input6_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'an7max', 'input7_cfg.scalingConfig.euMax', 'REAL', 1.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
PLCChannel(PLC_IP_ADDRESS, 'pondvolumetotal', 'pondVolumeTotal', 'REAL', 100.0, 600, map_=False, write_enabled=False, plc_type="Micro800"),
|
||||
|
||||
]
|
||||
|
||||
|
||||
@@ -104,10 +122,12 @@ class start(threading.Thread, deviceBase):
|
||||
|
||||
def run(self):
|
||||
"""Actually run the driver."""
|
||||
self.nodes["multisensor_0199"] = self
|
||||
for i in range(0, WAIT_FOR_CONNECTION_SECONDS):
|
||||
print("multisensor driver will start in {} seconds".format(WAIT_FOR_CONNECTION_SECONDS - i))
|
||||
time.sleep(1)
|
||||
log.info("BOOM! Starting multisensor driver...")
|
||||
|
||||
|
||||
self._check_watchdog()
|
||||
self._check_ip_address()
|
||||
@@ -129,8 +149,11 @@ class start(threading.Thread, deviceBase):
|
||||
self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'multisensor')
|
||||
time.sleep(2)
|
||||
|
||||
for i in range(0, 8):
|
||||
self.read_pond_calibration(i)
|
||||
|
||||
# print("multisensor driver still alive...")
|
||||
|
||||
log.info("multisensor driver still alive...")
|
||||
if self.force_send:
|
||||
if send_loops > 2:
|
||||
log.warning("Turning off force_send")
|
||||
@@ -151,13 +174,19 @@ class start(threading.Thread, deviceBase):
|
||||
last_read_height = -1.0
|
||||
cal_values = []
|
||||
cal_index = 1
|
||||
|
||||
height_tags = []
|
||||
volume_tags = []
|
||||
for i in range(0, 11):
|
||||
height_tags.append("input{}.calibrationLevel[{}]".format(input_number, i))
|
||||
volume_tags.append("input{}.calibrationVolume[{}]".format(input_number, i))
|
||||
|
||||
height_values = read_tag_group(PLC_IP_ADDRESS, height_tags, plc_type="Micro800")
|
||||
volume_values = read_tag_group(PLC_IP_ADDRESS, volume_tags, plc_type="Micro800")
|
||||
|
||||
while last_read_height != 0 and cal_index <= 10:
|
||||
cal_tag_height = "input{}.calibrationLevel[{}]".format(input_number, cal_index)
|
||||
cal_tag_volume = "input{}.calibrationVolume[{}]".format(input_number, cal_index)
|
||||
read_height = read_tag(PLC_IP_ADDRESS, cal_tag_height, plc_type="Micro800")
|
||||
time.sleep(2)
|
||||
read_volume = read_tag(PLC_IP_ADDRESS, cal_tag_volume, plc_type="Micro800")
|
||||
time.sleep(2)
|
||||
read_height = height_values[cal_index]
|
||||
read_volume = volume_values[cal_index]
|
||||
if read_height and read_volume:
|
||||
if read_height[0] > 0.0:
|
||||
cal_values.append({"height": read_height[0], "volume": read_volume[0]})
|
||||
@@ -170,6 +199,68 @@ class start(threading.Thread, deviceBase):
|
||||
self.sendtodbDev(1, calibration_channel, calibration_string, 0, 'multisensor')
|
||||
CALIBRATION_TABLES[input_number] = cal_values
|
||||
|
||||
def multisensor_addcalibrationpoint(self, name, value):
|
||||
"""Add a calibration point."""
|
||||
# value = {"input": int, "height": float, "volume": float}
|
||||
|
||||
try:
|
||||
# parse json values, throw an error if one is missing
|
||||
value = value.replace("'", '"')
|
||||
parsed = json.loads(value)
|
||||
input_number = int(parsed['input'])
|
||||
height = float(parsed['height'])
|
||||
volume = float(parsed['volume'])
|
||||
# write values to the tags
|
||||
level_inp_tag = "input{}_cmd.inpCalLevel".format(input_number)
|
||||
volume_inp_tag = "input{}_cmd.inpCalVolume".format(input_number)
|
||||
cmd_tag = "input{}_cmd.cmdInsertCalPoint".format(input_number)
|
||||
insert_success_tag = "input{}.insertSuccess".format(input_number)
|
||||
|
||||
write_height = write_tag(PLC_IP_ADDRESS, level_inp_tag, height, plc_type="Micro800")
|
||||
time.sleep(2)
|
||||
write_volume = write_tag(PLC_IP_ADDRESS, volume_inp_tag, volume, plc_type="Micro800")
|
||||
time.sleep(2)
|
||||
if write_height and write_volume:
|
||||
write_cmd = write_tag(PLC_IP_ADDRESS, cmd_tag, 1, plc_type="Micro800")
|
||||
time.sleep(2)
|
||||
if write_cmd:
|
||||
self.read_pond_calibration(input_number)
|
||||
return True
|
||||
return "Didn't write insert command correctly."
|
||||
return "Didn't write height or volume correctly."
|
||||
except KeyError as e:
|
||||
return "Couldn't parse input value: {} -- {}".format(value, e)
|
||||
|
||||
def multisensor_deletecalibrationpoint(self, name, value):
|
||||
"""Delete a calibration point from a calibration table"""
|
||||
# {"input": int, "point": int}
|
||||
value = value.replace("'", '"')
|
||||
parsed = json.loads(value)
|
||||
try:
|
||||
input_number = int(parsed['input'])
|
||||
point_number = int(parsed['point'])
|
||||
|
||||
delete_index_tag = "input{}_cmd.inpDeleteIndex".format(input_number)
|
||||
delete_cmd_tag = "input{}_cmd.cmdDeleteCalPoint".format(input_number)
|
||||
|
||||
write_point = write_tag(PLC_IP_ADDRESS, delete_index_tag, point_number, plc_type="Micro800")
|
||||
time.sleep(2)
|
||||
if write_point:
|
||||
write_cmd = write_tag(PLC_IP_ADDRESS, delete_cmd_tag, 1, plc_type="Micro800")
|
||||
time.sleep(2)
|
||||
if write_cmd:
|
||||
self.read_pond_calibration(input_number)
|
||||
return True
|
||||
log.error("Didn't write delete command correctly.")
|
||||
return "Didn't write delete command correctly."
|
||||
log.error("Didn't write pond or point correctly.")
|
||||
return "Didn't write pond or point correctly."
|
||||
except KeyError as e:
|
||||
return "Couldn't parse input value: {} -- {}".format(value, e)
|
||||
except Exception as e:
|
||||
log.error("Caught error in _deletecalibrationpoint({}, {}): {}".format(name, value, e))
|
||||
return e
|
||||
|
||||
def _check_watchdog(self):
|
||||
"""Check the watchdog and send to Meshify if changed or stale."""
|
||||
test_watchdog = self.multisensor_watchdog()
|
||||
@@ -209,11 +300,22 @@ class start(threading.Thread, deviceBase):
|
||||
|
||||
def multisensor_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)
|
||||
print("Result of multisensor_writeplctag(self, {}, {}) = {}".format(name, value, write_res))
|
||||
if write_res is None:
|
||||
write_res = "Error writing to PLC..."
|
||||
return write_res
|
||||
# {"tag": string, "val": }
|
||||
try:
|
||||
new_val = json.loads(str(value).replace("'", '"'))
|
||||
tag_n = str(new_val['tag']) # "cmd_Start"
|
||||
val_n = new_val['value']
|
||||
write_res = write_tag(str(PLC_IP_ADDRESS), tag_n, val_n, plc_type="Micro800")
|
||||
print("Result of multisensor_writeplctag(self, {}, {}, plc_type=\"Micro800\") = {}".format(name, value, write_res))
|
||||
if write_res is None:
|
||||
write_res = "Error writing to PLC..."
|
||||
return write_res
|
||||
except ValueError as e:
|
||||
log.error("Error writing to PLC: {}\n{}".format(value, e))
|
||||
return e
|
||||
except KeyError as e:
|
||||
log.error("KeyError for key {} in JSON object: {}".format(e, value))
|
||||
return e
|
||||
except Exception as e:
|
||||
log.error("Caught error in _writeplctag({}, {}): {}".format(name, value, e))
|
||||
return e
|
||||
|
||||
30
POCloud/python-driver/test.py
Normal file
30
POCloud/python-driver/test.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from channel import write_tag, read_tag
|
||||
import json
|
||||
from file_logger import filelogger as log
|
||||
|
||||
PLC_IP_ADDRESS = "10.20.4.18"
|
||||
|
||||
value = "{'tag': 'input1_cfg.ispond', 'value': 1}"
|
||||
|
||||
# {"tag": string, "val": }
|
||||
try:
|
||||
new_val = json.loads(str(value).replace("'", '"'))
|
||||
tag_n = str(new_val['tag']) # "cmd_Start"
|
||||
val_n = new_val['value']
|
||||
print("IP_ADDRESS: {}, VALUES: {} -- {}".format(PLC_IP_ADDRESS, tag_n, val_n))
|
||||
write_res = write_tag(str(PLC_IP_ADDRESS), tag_n, val_n, plc_type="Micro800")
|
||||
print("Result of multisensor_writeplctag(self, name, {}, plc_type=\"Micro800\") = {}".format(value, write_res))
|
||||
if write_res is None:
|
||||
write_res = "Error writing to PLC..."
|
||||
print(write_res)
|
||||
# return write_res
|
||||
except ValueError as e:
|
||||
log.error("Error writing to PLC: {}\n{}".format(value, e))
|
||||
# return e
|
||||
except KeyError as e:
|
||||
log.error("KeyError for key {} in JSON object: {}".format(e, value))
|
||||
# return e
|
||||
# except Exception as e:
|
||||
# log.error("Caught error in _writeplctag({}): {}".format(value, e))
|
||||
# return e
|
||||
|
||||
Reference in New Issue
Block a user