Files
2024-10-04 18:53:54 -05:00

417 lines
13 KiB
Python

import types
import traceback
import binascii
import threading
import time
import thread
import os
import struct
import sys
import serial
import minimalmodbus
import pickle
_NUMBER_OF_BYTES_PER_REGISTER = 2
class start(threading.Thread):
"""\
This class extends one of our base classes and is intended as an
example of a concrete, example implementation, but it is not itself
meant to be included as part of our developer API. Please consult the
base class documentation for the API and the source code for this file
for an example implementation.
"""
# here are the setting defaults
DEF_HEXDEC = True
DEF_EOLN = None
DEF_CHARTOUT = 2.0
# a sanity value to prevent an infinite rcv_buffer creation
DEF_MAX_READ = 1000
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)
self.daemon = True
self.offset = offset
self.company = companyId
self.name = name
self.number = number
self.q = Q
self.deviceName = name + '_[' + mac + ':' + number[0:2] + ':' + number[2:] + ']!'
self.chName = "at1" + '_[' + mac + ':'
print 'device name is:'
print self.deviceName
mac2 = mac.replace(":", "")
self.mac = mac2.upper()
self.address = 1
self.debug = True
self.mcu = mcu
self.firstRun = True
self.version = "15"
self.mqtt = mqtt
self.maxRegister = 65
#empty placeholders for the last values
self.register()
#make the serial connection:
try:
self.instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1) # port name, slave address (in decimal)
self.instrument.debug = True
self.instrument.serial.port # this is the serial port name
self.instrument.serial.parity = serial.PARITY_NONE
self.instrument.serial.xonxoff = False
self.instrument.serial.baudrate = 9600 # Baud
self.instrument.serial.bytesize = 8
self.instrument.serial.stopbits = 1
self.instrument.serial.timeout = 1 # seconds
self.instrument.address = 2
except Exception,e:
self.sendtodb("error", str(e), 0)
self.finished = threading.Event()
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)
self.last_wlevel = {}
self.last_tlevel = {}
self.last_temp = {}
self.last_overFlow = {}
for i in range(10, self.maxRegister):
self.last_wlevel[i] = 0
self.last_tlevel[i] = 0
self.last_temp[i] = 0
self.last_overFlow[i] = ""
def stop (self):
self.finished.set()
self.join()
def sendtodbCH(self, ch, channel, value, timestamp):
if int(ch) < 10:
ch = "0" + str(ch)
dname = self.chName + str(ch) + ":99]!"
if int(timestamp) == 0:
timestamp = self.getTime()
topic = 'meshify/db/%s/%s/%s/%s' % (self.company, self.mac, dname, channel)
print topic
msg = """[ { "value":"%s", "timestamp":"%s" } ]""" % (str(value), str(timestamp))
print msg
self.q.put([topic, msg, 0])
def sendtodb(self, channel, value, timestamp):
if int(timestamp) == 0:
timestamp = self.getTime()
if timestamp < 1400499858:
return
topic = 'meshify/db/%s/%s/%s/%s' % (self.company, self.mac, self.deviceName, channel)
print topic
msg = """[ { "value":"%s", "timestamp":"%s" } ]""" % (str(value), str(timestamp))
print msg
self.q.put([topic, msg, 0])
def start(self):
# you could add other ddo settings here
thread.start_new_thread(self.loop, ())
# def stop(): uses XBeeSerial.stop()
## Locally defined functions:
def gps(self):
try:
resp = False
ser = serial.Serial(port='/dev/ttyS3', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, xonxoff=False)
ser.open
time.sleep(2)
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
time.sleep(1)
response = ser.readline()
print response
latNeg = ""
longNeg = ""
if response.split(',')[0] == "$GPRMC":
lat = response.split(',')[3]
if response.split(',')[4] == "S":
latNeg = "-"
longitude = response.split(',')[5]
if response.split(',')[6] == "W":
longNeg = "-"
elif response.split(',')[0] == "$GPGGA":
lat = response.split(',')[2]
if response.split(',')[3] == "S":
latNeg = "-"
longitude = response.split(',')[4]
if response.split(',')[5] == "W":
longNeg = "-"
else:
return
googlelat = (latNeg + str(((int(lat.split(".")[0][:2])) + ( float(((lat.split(".")[0][-2:]) + "." + lat.split(".")[1])) / 60) )))
googlelong = (longNeg + str(((int(longitude.split(".")[0][:3])) + ( float(((longitude.split(".")[0][-2:]) + "." + longitude.split(".")[1])) / 60) )))
googlelat = str(round(float(googlelat), 4))
googlelong = str(round(float(googlelong), 4))
if googlelat != self.lastLat or googlelong != self.lastLong:
print googlelat, googlelong
value = googlelat + "," + googlelong
if value != "24.0,121.0" and value!= "0.0,0.0":
resp = True
self.sendtodb("gps", value, 0)
else:
resp = False
self.lastLat = googlelat
self.lastLong = googlelong
ser.close()
return resp
except Exception,e:
print e
try:
ser.close()
except:
pass
pass
def signal(self):
try:
ser = serial.Serial(port='/dev/modem_at1', timeout=2, baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, xonxoff=False)
ser.open
time.sleep(2)
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
time.sleep(.5)
ser.write("AT+CSQ" + chr(13))
print("write data: AT+CSQ")
time.sleep(0.5)
response = ser.readlines()
response = response[1].split(",")[0].replace("+CSQ:", "").strip()
response = (-113 + (int(response) * 2))
print response
ser.close()
return str(response)
#self.sendtodb("signal", str(response), 0)
except:
try:
ser.close()
except:
pass
pass
def checkTemp(self):
temp = os.popen('/usr/sbin/mts-io-sysfs show board-temperature')
temp1 = temp.read()
temp1 = temp1.strip()
self.sendtodb("temp", temp1, 0)
temp.close()
def run(self):
#on startup send the version number
self.sendtodb("version", str(self.version), 0)
self.sendtodb("log", "Tank Level Start Up", 0)
self.count = 3001
hb_count = 0
while not self.finished.isSet():
self.count += 1
try:
for i in range(10, self.maxRegister):
print "################################"
print "#############sending data ######"
try:
self.instrument.address = i
connected = int(self.mqtt._state)
if connected == 1:
pause = .1
else:
pause = 5
time.sleep(pause)
tlevel = self.instrument.read_float(1, functioncode=3) # Registernumber, number of decimals
tlevel = round(tlevel, 1)
print tlevel
if tlevel != self.last_tlevel[i]:
self.sendtodbCH(str(i), "tlevel", str(tlevel), 0)
self.last_tlevel[i] = tlevel
time.sleep(pause)
wlevel = self.instrument.read_float(3, functioncode=3) # Registernumber, number of decimals
wlevel = round(wlevel, 1)
print wlevel
if wlevel != self.last_wlevel[i]:
self.sendtodbCH(str(i), "wlevel", str(wlevel), 0)
self.last_wlevel[i] = wlevel
time.sleep(pause)
temp = self.instrument.read_float(5, functioncode=3) # Registernumber, number of decimals
temp = int(temp)
print temp
if abs(temp - self.last_temp[i]) > 1:
self.sendtodbCH(str(i), "temp", str(temp), 0)
self.last_temp[i] = temp
overflow = self.instrument.read_float(7, functioncode=3) # Registernumber, number of decimals
overflow = int(overflow)
print overflow
if overFlow == 1:
overFlow = "On"
elif overFlow == 0:
overFlow = "Off"
if overFlow != self.last_overFlow[i]:
self.sendtodbCH(str(i), "high", str(overFlow), 0)
self.last_overFlow[i] = overFlow
if self.count > 3000:
sig = self.signal()
self.sendtodbCH(str(i), "signal", str(sig), 0)
except Exception,e:
print e
#self.sendtodb("error", str(e), 0)
if self.count > 3000:
self.count = 0
try:
for i in range(10, self.maxRegister):
self.last_wlevel[i] = 0
self.last_tlevel[i] = 0
self.last_temp[i] = 0
except:
pass
except Exception,e:
self.sendtodb("error", str(e), 0)
def getModbus(self):
return self.modbusData
def readRegister(self, value):
self.sendtodb("readRegister", value, 0)
register = data.value
print "here is the reg value"
print register
if register.startswith("3"):
register = register[2:]
register = int(register)
register = register - 1
print "new reg value:"
print register
resp = self.read_register(register, 0, functioncode=4)
print resp
elif register.startswith("4"):
register = register[2:]
register = int(register)
register = register - 1
print "new reg value:"
print register
resp = self.read_registers(register, 20, functioncode=3)
print resp
# internal functions & classes
def atw_sync(self, name, value):
self.sendtodb("connected", "true", 0)
self.register()
return True
def get_eoln(self):
eoln = SettingsBase.get_setting(self, "eoln")
if eoln is None:
return None
if eoln != self.__eoln_save:
# cache result to avoid repeat processing of escapes
self.__eoln_save = eoln
self._eoln = strip_escapes(eoln)
return self._eoln
def getTime(self):
return str(int(time.time() + int(self.offset)))