164 lines
7.1 KiB
Python
164 lines
7.1 KiB
Python
#!/usr/bin/python
|
|
|
|
import traceback
|
|
import threading
|
|
import time
|
|
import os
|
|
from device_base import deviceBase
|
|
from datetime import datetime
|
|
import requests
|
|
import json
|
|
import calendar
|
|
import pickle
|
|
import minimalmodbus
|
|
import minimalmodbusM1
|
|
|
|
|
|
class start(threading.Thread, deviceBase):
|
|
|
|
def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, companyId=None, offset=None, mqtt=None, Nodes=None):
|
|
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()
|
|
|
|
# Setup Modbus Connection
|
|
baud = 115200
|
|
mb_connected = False
|
|
while not mb_connected:
|
|
mb_connected = self.mcu.set232Baud(baud)
|
|
time.sleep(1)
|
|
|
|
ser232 = self.mcu.rs232
|
|
self.modbus_interface = minimalmodbusM1.Instrument(1, ser232)
|
|
self.modbus_interface.address = 1
|
|
self.event_log = []
|
|
|
|
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):
|
|
self.sendtodb("connected", "True", 0)
|
|
|
|
def run(self):
|
|
first_scan = True
|
|
|
|
try:
|
|
with open('eventlog.pickle', 'rb') as evt_pickle:
|
|
self.event_log = pickle.load(evt_pickle)
|
|
print "found pickled Event Log dictionary: {0}".format(self.event_log)
|
|
except:
|
|
print "couldn't load Event Log from pickle"
|
|
|
|
|
|
|
|
# Dynamic Alarms
|
|
dyn_alarm_registers = {
|
|
1: {'ch': 'norpm', 'last_value': None, 'last_send': 0},
|
|
2: {'ch': 'nocrank', 'last_value': None, 'last_send': 0},
|
|
3: {'ch': 'beltslippage', 'last_value': None, 'last_send': 0},
|
|
4: {'ch': 'peakpolishedrodhp', 'last_value': None, 'last_send': 0},
|
|
5: {'ch': 'vfdpeakloadlimit', 'last_value': None, 'last_send': 0},
|
|
6: {'ch': 'vfdminloadlimit', 'last_value': None, 'last_send': 0},
|
|
7: {'ch': 'invalidhoadigital', 'last_value': None, 'last_send': 0},
|
|
8: {'ch': 'invalidlinearpumpdigital', 'last_value': None, 'last_send': 0},
|
|
9: {'ch': 'cryoutalarm', 'last_value': None, 'last_send': 0},
|
|
10: {'ch': 'vfdcommerror', 'last_value': None, 'last_send': 0},
|
|
11: {'ch': 'vfddrivefaulterror', 'last_value': None, 'last_send': 0},
|
|
12: {'ch': 'vfddrivefaultbypass', 'last_value': None, 'last_send': 0},
|
|
13: {'ch': 'vfddrivepardifference', 'last_value': None, 'last_send': 0},
|
|
14: {'ch': 'vfdkeypadcontrol', 'last_value': None, 'last_send': 0},
|
|
15: {'ch': 'vfdswitchoff', 'last_value': None, 'last_send': 0},
|
|
16: {'ch': 'vfdpresswengaged', 'last_value': None, 'last_send': 0},
|
|
17: {'ch': 'invalidtubingsize', 'last_value': None, 'last_send': 0},
|
|
18: {'ch': 'vfddrivebypassswengaged', 'last_value': None, 'last_send': 0},
|
|
19: {'ch': 'vfdabbigbtfansnotconfig', 'last_value': None, 'last_send': 0},
|
|
20: {'ch': 'vfdabbigbtfansconflict', 'last_value': None, 'last_send': 0}
|
|
}
|
|
|
|
# Latched Alarms
|
|
latched_alarm_registers = {
|
|
33: {'ch': 'changeinprogramming', 'last_value': None, 'last_send': 0},
|
|
34: {'ch': 'resettodefaults', 'last_value': None, 'last_send': 0},
|
|
35: {'ch': 'changepassword', 'last_value': None, 'last_send': 0},
|
|
37: {'ch': 'vfddrivefaulterror', 'last_value': None, 'last_send': 0},
|
|
38: {'ch': 'vfddrivefaultbypass', 'last_value': None, 'last_send': 0},
|
|
39: {'ch': 'vfdkeypadcontrol', 'last_value': None, 'last_send': 0},
|
|
40: {'ch': 'vfdswitchoff', 'last_value': None, 'last_send': 0},
|
|
41: {'ch': 'vfdpresswengaged', 'last_value': None, 'last_send': 0},
|
|
42: {'ch': 'malfunctionlockout', 'last_value': None, 'last_send': 0},
|
|
43: {'ch': 'vfddrivebypassswengaged', 'last_value': None, 'last_send': 0},
|
|
44: {'ch': 'vfdabbigbtfansnotconfig', 'last_value': None, 'last_send': 0},
|
|
45: {'ch': 'vfdabbigbtfansconflict', 'last_value': None, 'last_send': 0}
|
|
}
|
|
|
|
def check_alarm_register(register, prefix, obj):
|
|
channel = "{}_{}".format(prefix, obj['ch'])
|
|
test_coil = self.modbus_interface.read_bit(register, functioncode=1)
|
|
if not (test_coil == obj['last_value']) or (time.time() - obj['last_send']) > 3600:
|
|
self.sendtodb(channel, test_coil, 0)
|
|
obj['last_value'] = test_coil
|
|
obj['last_send'] = time.time()
|
|
return obj
|
|
|
|
|
|
while True:
|
|
try:
|
|
dyn_alarm_act = not self.modbus_interface.read_bit(32, functioncode=1) == 0
|
|
latched_alarm_act = not self.modbus_interface.read_bit(64, functioncode=1) == 0
|
|
except Exception as e:
|
|
print("Unable to get alarm active tags:\n{}".format(e))
|
|
|
|
if dyn_alarm_act or first_scan:
|
|
print("There's a dynamic alarm")
|
|
for r in dyn_alarm_registers:
|
|
try:
|
|
dyn_alarm_registers[r] = check_alarm_register(r, 'alarm_dyn', dyn_alarm_registers[r])
|
|
except Exception as e:
|
|
print("Error during dyn_alarm_registers loop:\n{}".format(e))
|
|
continue
|
|
else:
|
|
print("No dynamic alarms")
|
|
|
|
if latched_alarm_act or first_scan:
|
|
print("There's a latched alarm")
|
|
for r in latched_alarm_registers:
|
|
try:
|
|
latched_alarm_registers[r] = check_alarm_register(r, 'alarm_lat', latched_alarm_registers[r])
|
|
except Exception as e:
|
|
print("Error during latched_alarm_registers loop:\n{}".format(e))
|
|
continue
|
|
else:
|
|
print("No latched alarms")
|
|
|
|
self.check_EventLog()
|
|
|
|
first_scan = False
|
|
time.sleep(10)
|
|
|
|
|
|
def check_EventLog(self):
|
|
end_of_eventlog = False
|
|
event_log_changed = False
|
|
event_log_index = 0
|
|
while not end_of_eventlog:
|
|
event_dt_register = 802 + event_log_index
|
|
event_id_register = 602 + event_log_index
|
|
event_dt = self.modbus_interface.read_register(event_dt_register, functioncode=4)
|
|
if not event_dt in self.event_log:
|
|
event_id = self.modbus_interface.read_register(event_id_register, functioncode=4)
|
|
# self.sendtodb('event_log', '{"event_id":{}, "event_dt": {}}'.format(event_id, event_dt), event_dt)
|
|
print('{"event_id":{}, "event_dt": {}}'.format(event_id, event_dt))
|
|
self.event_log.append(event_dt)
|
|
event_log_changed = True
|
|
else:
|
|
end_of_eventlog = True
|
|
if event_log_changed:
|
|
with open('event_log.pickle', 'wb') as handle:
|
|
pickle.dump(self.event_log, handle)
|
|
return True
|
|
|