352 lines
22 KiB
Python
352 lines
22 KiB
Python
#!/usr/bin/python
|
|
|
|
|
|
import threading
|
|
import time
|
|
from device_base import deviceBase
|
|
import micro800 as u800
|
|
|
|
channels = {}
|
|
addr = '192.168.1.40'
|
|
|
|
|
|
class Channel():
|
|
def read(self):
|
|
valData = u800.readMicroTag(self.device_addr, self.tag)
|
|
if valData:
|
|
nowVal = valData[0]
|
|
if self.map_obj:
|
|
nowVal = self.map_obj[nowVal]
|
|
self.data_type = valData[1]
|
|
if self.data_type == "BOOL" or self.map_obj:
|
|
if self.last_value == "":
|
|
self.sendFn(self.name, nowVal, 0)
|
|
self.last_time_uploaded = time.time()
|
|
self.last_value = nowVal
|
|
elif (not (self.last_value == nowVal)) or ((time.time() - self.last_time_uploaded) > self.max_time_between_uploads):
|
|
self.sendFn(self.name, nowVal, 0)
|
|
self.last_time_uploaded = time.time()
|
|
self.last_value = nowVal
|
|
elif (self.data_type == "REAL") or (self.data_type[-3:] == "INT"):
|
|
if self.last_value == "":
|
|
self.sendFn(self.name, nowVal, 0)
|
|
self.last_time_uploaded = time.time()
|
|
self.last_value = nowVal
|
|
elif (abs(self.last_value - nowVal) > self.change_threshold) or ((time.time() - self.last_time_uploaded) > self.max_time_between_uploads):
|
|
self.sendFn(self.name, nowVal, 0)
|
|
self.last_time_uploaded = time.time()
|
|
self.last_value = nowVal
|
|
return True
|
|
return False
|
|
|
|
def __init__(self, name, tag, max_time_between_uploads, sendFn, change_threshold=0.0, writeable=False, map_obj=None):
|
|
global addr
|
|
self.name = name
|
|
self.tag = tag
|
|
self.data_type = ''
|
|
self.last_value = ''
|
|
self.last_time_uploaded = 0
|
|
self.change_threshold = change_threshold
|
|
self.max_time_between_uploads = int(max_time_between_uploads)
|
|
self.sendFn = sendFn
|
|
self.device_addr = addr
|
|
self.writeable = bool(writeable)
|
|
self.map_obj = map_obj
|
|
self.read()
|
|
|
|
def write(self, val, handshake=None, handshake_val=None):
|
|
if self.writeable:
|
|
h = handshake
|
|
hval = handshake_val
|
|
if h is None:
|
|
if u800.writeMicroTag(self.device_addr, self.tag, val):
|
|
self.sendFn(self.name, val, time.time())
|
|
self.last_value = val
|
|
return True
|
|
else:
|
|
return False
|
|
else:
|
|
return u800.writeMicroTag(self.device_addr, self.tag, val, handshake=h, handshake_val=hval)
|
|
else:
|
|
print("NOT ALLOWED TO WRITE TO {}".format(self.name))
|
|
return False
|
|
|
|
|
|
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):
|
|
global addr, channels
|
|
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)
|
|
print("!!! Made it to Driver init() !!!")
|
|
self.daemon = True
|
|
self.version = "3"
|
|
self.finished = threading.Event()
|
|
threading.Thread.start(self)
|
|
self.last_channel_send = 0
|
|
self.device_address = addr
|
|
|
|
def setupChannels(self):
|
|
global channels
|
|
channels = {
|
|
'alarmengineoilpressurehifault': Channel('alarmengineoilpressurehifault', 'alarm_EngineOilPressure_HiFault', 360, self.sendtodbJSON, writeable=False),
|
|
'alarmengineoilpressurelofault': Channel('alarmengineoilpressurelofault', 'alarm_EngineOilPressure_LoFault', 360, self.sendtodbJSON, writeable=False),
|
|
'alarmhydraulicfluidtemphifault': Channel('alarmhydraulicfluidtemphifault', 'alarm_HydraulicFluidTemp_HiFault', 360, self.sendtodbJSON, writeable=False),
|
|
'alarmhydraulicpressurehifault': Channel('alarmhydraulicpressurehifault', 'alarm_HydraulicPressure_HiFault', 360, self.sendtodbJSON, writeable=False),
|
|
'alarminvalidstate': Channel('alarminvalidstate', 'alarm_InvalidState', 360, self.sendtodbJSON, writeable=False),
|
|
'alarmmotorstartuptimeout': Channel('alarmmotorstartuptimeout', 'alarm_MotorStartupTimeout', 360, self.sendtodbJSON, writeable=False),
|
|
'alarmstrokeoverlap': Channel('alarmstrokeoverlap', 'alarm_StrokeOverlap', 360, self.sendtodbJSON, writeable=False),
|
|
'alarmtimeoutduringlifting': Channel('alarmtimeoutduringlifting', 'alarm_TimeoutDuringLifting', 360, self.sendtodbJSON, writeable=False),
|
|
'cfgcylinderid': Channel('cfgcylinderid', 'cfg_CylinderID', 360, self.sendtodbJSON, change_threshold=0.5, writeable=True),
|
|
'cfgenginehourswarning': Channel('cfgenginehourswarning', 'cfg_EngineHours_Warning', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgengineoilpressureeumax': Channel('cfgengineoilpressureeumax', 'cfg_EngineOilPressure_EUMax', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgengineoilpressureeumin': Channel('cfgengineoilpressureeumin', 'cfg_EngineOilPressure_EUMin', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgengineoilpressurehifault': Channel('cfgengineoilpressurehifault', 'cfg_EngineOilPressure_HiFault', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgengineoilpressurelofault': Channel('cfgengineoilpressurelofault', 'cfg_EngineOilPressure_LoFault', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgenginerunningoilpressure': Channel('cfgenginerunningoilpressure', 'cfg_EngineRunning_OilPressure', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgfaultedmotorshutdownmins': Channel('cfgfaultedmotorshutdownmins', 'cfg_FaultedMotorShutdownMins', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydfluidcoolerenabled': Channel('cfghydfluidcoolerenabled', 'cfg_HydFluidCooler_Enabled', 360, self.sendtodbJSON, writeable=True),
|
|
'cfghydfluidcoolertempoff': Channel('cfghydfluidcoolertempoff', 'cfg_HydFluidCooler_TempOff', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydfluidcoolertempon': Channel('cfghydfluidcoolertempon', 'cfg_HydFluidCooler_TempOn', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydfluidtempeumax': Channel('cfghydfluidtempeumax', 'cfg_HydFluidTemp_EUMax', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydfluidtempeumin': Channel('cfghydfluidtempeumin', 'cfg_HydFluidTemp_EUMin', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydfluidtemphifault': Channel('cfghydfluidtemphifault', 'cfg_HydFluidTemp_HiFault', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydfluidtemphiwarning': Channel('cfghydfluidtemphiwarning', 'cfg_HydFluidTemp_HiWarning', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydfluidtemphiwarningmultiplier': Channel('cfghydfluidtemphiwarningmultiplier', 'cfg_HydFluidTemp_HiWarningMultiplier', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydpressclosesp': Channel('cfghydpressclosesp', 'cfg_HydPress_CloseSP', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydpresseumax': Channel('cfghydpresseumax', 'cfg_HydPress_EUMax', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydpresseumin': Channel('cfghydpresseumin', 'cfg_HydPress_EUMin', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydpresshifault': Channel('cfghydpresshifault', 'cfg_HydPress_HiFault', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfghydpressliftingsp': Channel('cfghydpressliftingsp', 'cfg_HydPress_LiftingSP', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgliftingtimetimeout': Channel('cfgliftingtimetimeout', 'cfg_LiftingTimeTimeout', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgpolishedrodod': Channel('cfgpolishedrodod', 'cfg_PolishedRodOD', 360, self.sendtodbJSON, change_threshold=0.01, writeable=True),
|
|
'cfgspmtarget': Channel('cfgspmtarget', 'cfg_SPMTarget', 360, self.sendtodbJSON, change_threshold=0.001, writeable=True),
|
|
'cmdengineresethourmeter': Channel('cmdengineresethourmeter', 'cmd_EngineResetHourMeter', 360, self.sendtodbJSON, writeable=True),
|
|
'cmdenginestart': Channel('cmdenginestart', 'cmd_EngineStart', 360, self.sendtodbJSON, writeable=True),
|
|
'cmdenginestop': Channel('cmdenginestop', 'cmd_EngineStop', 360, self.sendtodbJSON, writeable=True),
|
|
'cmdresetfault': Channel('cmdresetfault', 'cmd_ResetFault', 360, self.sendtodbJSON, writeable=True),
|
|
'cmdresetstrokelifetime': Channel('cmdresetstrokelifetime', 'cmd_ResetStrokeLifetime', 360, self.sendtodbJSON, writeable=True),
|
|
'cmdrun': Channel('cmdrun', 'cmd_Run', 360, self.sendtodbJSON, writeable=False),
|
|
'cmdstart': Channel('cmdstart', 'cmd_Start', 360, self.sendtodbJSON, writeable=True),
|
|
'cmdstop': Channel('cmdstop', 'cmd_Stop', 360, self.sendtodbJSON, writeable=True),
|
|
'countstrokelifetime': Channel('countstrokelifetime', 'count_StrokeLifetime', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False),
|
|
'countstrokestartup': Channel('countstrokestartup', 'count_StrokeStartup', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False),
|
|
'countstroketoday': Channel('countstroketoday', 'count_StrokeToday', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False),
|
|
'outenginestart': Channel('outenginestart', 'out_EngineStart', 360, self.sendtodbJSON, writeable=False),
|
|
'outenginestop': Channel('outenginestop', 'out_EngineStop', 360, self.sendtodbJSON, writeable=False),
|
|
'outhydfluidcooler': Channel('outhydfluidcooler', 'out_HydFluidCooler', 360, self.sendtodbJSON, writeable=False),
|
|
'rpallok': Channel('rpallok', 'rp_AllOK', 360, self.sendtodbJSON, writeable=False),
|
|
'rpengine': Channel('rpengine', 'rp_Engine', 360, self.sendtodbJSON, writeable=False),
|
|
'spallok': Channel('spallok', 'sp_AllOK', 360, self.sendtodbJSON, writeable=False),
|
|
'spengine': Channel('spengine', 'sp_Engine', 360, self.sendtodbJSON, writeable=False),
|
|
'stsautomode': Channel('stsautomode', 'sts_AutoMode', 360, self.sendtodbJSON, writeable=False),
|
|
'stsenginehourswarning': Channel('stsenginehourswarning', 'sts_EngineHours_Warning', 360, self.sendtodbJSON, writeable=False),
|
|
'stsengineint': Channel('stsengineint', 'sts_EngineINT', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False, map_obj={0: 'Stopped', 1: 'Starting', 2: 'Running', 3: 'Stopping'}),
|
|
'stsengineoilpressurehifault': Channel('stsengineoilpressurehifault', 'sts_EngineOilPressure_HiFault', 360, self.sendtodbJSON, writeable=False),
|
|
'stsengineoilpressurelofault': Channel('stsengineoilpressurelofault', 'sts_EngineOilPressure_LoFault', 360, self.sendtodbJSON, writeable=False),
|
|
'stsenginerunning': Channel('stsenginerunning', 'sts_EngineRunning', 360, self.sendtodbJSON, writeable=False),
|
|
'stserrorcodeint': Channel('stserrorcodeint', 'sts_ErrorCode_INT', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False, map_obj={0: 'No Error', 1: 'Motor Startup Timeout', 2: 'Stroke Overlap', 3: 'Timeout During Lifting', 4: 'Invalid State', 5: 'Lost Run Permissive', 6: 'Lost Engine Run Permissive'}),
|
|
'stshydraulicfluidtemphifault': Channel('stshydraulicfluidtemphifault', 'sts_HydraulicFluidTemp_HiFault', 360, self.sendtodbJSON, writeable=False),
|
|
'stshydraulicfluidtemphiwarning': Channel('stshydraulicfluidtemphiwarning', 'sts_HydraulicFluidTemp_HiWarning', 360, self.sendtodbJSON, writeable=False),
|
|
'stshydraulicpressurehifault': Channel('stshydraulicpressurehifault', 'sts_HydraulicPressure_HiFault', 360, self.sendtodbJSON, writeable=False),
|
|
'stsmanualmode': Channel('stsmanualmode', 'sts_ManualMode', 360, self.sendtodbJSON, writeable=False),
|
|
'stsstep': Channel('stsstep', 'sts_Step', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False, map_obj={0: 'Engine Off', 1: 'Engine Startup', 2: 'Engine Idle', 3: 'Lifting', 4: 'Falling', 5: 'Faulted', 6: 'IO Test', 7: 'Manual Operation'}),
|
|
'ststestmode': Channel('ststestmode', 'sts_TestMode', 360, self.sendtodbJSON, writeable=False),
|
|
'timeenginehourmeter': Channel('timeenginehourmeter', 'time_EngineHourMeter', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False),
|
|
'timelastfallingtime': Channel('timelastfallingtime', 'time_LastFallingTime', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False),
|
|
'timelastliftingtime': Channel('timelastliftingtime', 'time_LastLiftingTime', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False),
|
|
'timesecondsperstroke': Channel('timesecondsperstroke', 'time_SecondsPerStroke', 360, self.sendtodbJSON, change_threshold=0.5, writeable=False),
|
|
'valengineoilpressure': Channel('valengineoilpressure', 'val_EngineOilPressure', 360, self.sendtodbJSON, change_threshold=2.0, writeable=False),
|
|
'valhydraulicfluidtemp': Channel('valhydraulicfluidtemp', 'val_HydraulicFluidTemp', 360, self.sendtodbJSON, change_threshold=2.0, writeable=False)
|
|
# 'valhydraulicpressure': Channel('valhydraulicpressure', 'val_HydraulicPressure', 360, self.sendtodbJSON, change_threshold=2.0, writeable=False),
|
|
# 'valpolishedrodload': Channel('valpolishedrodload', 'val_PolishedRodLoad', 360, self.sendtodbJSON, change_threshold=5.0, writeable=False),
|
|
}
|
|
|
|
def register(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
|
|
self.channels["status"]["last_value"] = ""
|
|
|
|
def readChannelData(self):
|
|
global channels
|
|
print "Executing readChannelData()"
|
|
runLoopStatus = ""
|
|
try:
|
|
for i in channels:
|
|
runLoopStatus = i
|
|
channels[i].read()
|
|
runLoopStatus = "Complete"
|
|
return True
|
|
except Exception, e:
|
|
print "Error during {0} of run loop: {1}".format(runLoopStatus, e)
|
|
return False
|
|
|
|
def checkLifting(self):
|
|
return u800.readMicroTag(self.device_address, 'sts_Step')[0] == 3
|
|
|
|
def checkFalling(self):
|
|
return u800.readMicroTag(self.device_address, 'sts_Step')[0] == 4
|
|
|
|
def checkIdle(self):
|
|
s = u800.readMicroTag(self.device_address, 'sts_Step')[0]
|
|
return not (s == 3) and not (s == 4)
|
|
|
|
def run(self):
|
|
global channels
|
|
self.sendLastStroke = True
|
|
self.sendCardEvery = 5
|
|
cardScanIndex = 0
|
|
PRLoadPoints = []
|
|
status = ""
|
|
self.setupChannels()
|
|
print("!!! Made it to Driver run() !!!")
|
|
while True:
|
|
if self.checkLifting():
|
|
# hydPressurePoints.append([time.time(), u800.readMicroTag(addr, 'val_HydraulicPressure')[0]])
|
|
PRLoadPoints.append([time.time(), u800.readMicroTag(addr, 'val_PolishedRodLoad')[0]])
|
|
if not status == "lifting":
|
|
status = "lifting"
|
|
self.sendtodbJSON('stsstep', 'Lifting', time.time())
|
|
print(status)
|
|
elif self.checkFalling():
|
|
# hydPressurePoints.append([time.time(), u800.readMicroTag(addr, 'val_HydraulicPressure')[0]])
|
|
PRLoadPoints.append([time.time(), u800.readMicroTag(addr, 'val_PolishedRodLoad')[0]])
|
|
if not status == "falling":
|
|
status = "falling"
|
|
self.sendtodbJSON('stsstep', 'Falling', time.time())
|
|
print(status)
|
|
elif self.checkIdle():
|
|
if not status == "idle":
|
|
status = "idle"
|
|
print(status)
|
|
cardScanIndex = cardScanIndex + 1
|
|
if cardScanIndex == self.sendCardEvery:
|
|
self.sendLastStroke = True
|
|
cardScanIndex = 0
|
|
if self.sendLastStroke:
|
|
pr_load_string = "["
|
|
for x in PRLoadPoints:
|
|
pr_load_string = pr_load_string + "[{0},{1}],".format(x[0], x[1])
|
|
pr_load_string = pr_load_string[:-1] + "]"
|
|
|
|
# hyd_press_string = "["
|
|
# for y in PRLoadPoints:
|
|
# hyd_press_string = hyd_press_string + "[{0},{1}],".format(y[0], y[1])
|
|
# hyd_press_string = hyd_press_string[:-1] + "]"
|
|
if len(PRLoadPoints) > 0:
|
|
self.sendtodbJSON('polishedrodloadcard', pr_load_string, time.time())
|
|
# self.sendtodbJSON('hydraulicpressurecard', hyd_press_string, time.time())
|
|
self.sendLastStroke = False
|
|
PRLoadPoints = []
|
|
self.readChannelData()
|
|
self.last_channel_send = time.time()
|
|
elif (time.time() - self.last_channel_send) > 10.0:
|
|
print('Checking channel data')
|
|
self.readChannelData()
|
|
self.last_channel_send = time.time()
|
|
time.sleep(0.1)
|
|
|
|
def henryhyd_sync(self, name, value):
|
|
self.sendtodb("connected", "true", 0)
|
|
return True
|
|
|
|
def genericSet(self, name, value, id):
|
|
try:
|
|
global channels
|
|
print("Trying to set {} to {} (type {})".format(channels[name].tag, value))
|
|
return channels[name].write(value)
|
|
except Exception, e:
|
|
print("Exception during genericSet: {}".format(e))
|
|
|
|
def henryhyd_cmdengineresethourmeter(self, name, value):
|
|
global channels
|
|
print('trying to set cmd_EngineResetHourMeter to {}'.format(value))
|
|
if int(value) == 1:
|
|
if channels[name].write(int(value), handshake="val_EngineHourMeter", handshake_val=0):
|
|
self.sendtodb('valenginehourmeter', 0, time.time())
|
|
channels['valenginehourmeter'].last_value = 0
|
|
channels['valenginehourmeter'].last_time_uploaded = time.time()
|
|
return True
|
|
return False
|
|
else:
|
|
return channels[name].write(value)
|
|
|
|
def henryhyd_cmdenginestart(self, name, value):
|
|
global channels
|
|
print('trying to set cmd_EngineStart to {}'.format(value))
|
|
if int(value) == 1:
|
|
if channels[name].write(int(value), handshake="sts_EngineRunning", handshake_val=1):
|
|
self.sendtodb('stsenginerunning', 1, time.time())
|
|
channels['stsenginerunning'].last_value = 1
|
|
channels['stsenginerunning'].last_time_uploaded = time.time()
|
|
return True
|
|
return False
|
|
else:
|
|
return channels[name].write(value)
|
|
|
|
def henryhyd_cmdenginestop(self, name, value):
|
|
global channels
|
|
print('trying to set cmd_EngineStop to {} for {}'.format(value, addr))
|
|
if int(value) == 1:
|
|
if channels[name].write(int(value), handshake="sts_EngineRunning", handshake_val=0):
|
|
self.sendtodb('stsenginerunning', 0, time.time())
|
|
channels['stsenginerunning'].last_value = 0
|
|
channels['stsenginerunning'].last_time_uploaded = time.time()
|
|
return True
|
|
return False
|
|
else:
|
|
return channels[name].write(value)
|
|
|
|
def henryhyd_cmdresetfault(self, name, value):
|
|
global channels
|
|
print('trying to set cmd_ResetFault to {}'.format(value))
|
|
if int(value) == 1:
|
|
if channels[name].write(int(value), handshake="sts_ErrorCode_INT", handshake_val=0):
|
|
self.sendtodb('stserrorcodeint', "No Error", time.time())
|
|
channels['stserrorcodeint'].last_value = 0
|
|
channels['stserrorcodeint'].last_time_uploaded = time.time()
|
|
return True
|
|
return False
|
|
else:
|
|
return channels[name].write(value)
|
|
|
|
def henryhyd_cmdresetstrokelifetime(self, name, value):
|
|
global channels
|
|
print('trying to set cmd_ResetStrokeLifetime to {}'.format(value))
|
|
if int(value) == 1:
|
|
if channels[name].write(int(value), handshake="count_StrokeLifetime", handshake_val=0):
|
|
self.sendtodb('countstrokelifetime', 0, time.time())
|
|
channels['countstrokelifetime'].last_value = 0
|
|
channels['countstrokelifetime'].last_time_uploaded = time.time()
|
|
return True
|
|
return False
|
|
else:
|
|
return channels[name].write(value)
|
|
|
|
def henryhyd_cmdstart(self, name, value):
|
|
global channels
|
|
print('trying to set cmd_Start to {}'.format(value))
|
|
if int(value) == 1:
|
|
if channels[name].write(int(value), handshake="cmd_Run", handshake_val=1):
|
|
self.sendtodb("cmdrun", 1, time.time())
|
|
channels['cmdrun'].last_value = 1
|
|
channels['cmdrun'].last_time_uploaded = time.time()
|
|
return True
|
|
else:
|
|
return "Error while attempting to start"
|
|
else:
|
|
return channels[name].write(value)
|
|
|
|
def henryhyd_cmdstop(self, name, value):
|
|
global channels
|
|
print('trying to set cmd_Stop to {}'.format(value))
|
|
if int(value) == 1:
|
|
if channels[name].write(int(value), handshake="cmd_Run", handshake_val=0):
|
|
self.sendtodb("cmdrun", 0, time.time())
|
|
channels['cmdrun'].last_value = 0
|
|
channels['cmdrun'].last_time_uploaded = time.time()
|
|
return True
|
|
else:
|
|
return "Error while attempting to stop."
|
|
else:
|
|
return channels[name].write(value)
|