Files
ThingsBoard/RPI Docker Test/SkyWaveDataAPI.py
2024-10-04 18:53:54 -05:00

493 lines
16 KiB
Python

import array
import serial
import time
import thread
import threading
import os
import binascii
class skywave():
def __init__(self, setCallback, mac, state, Q, mcu):
self.q = Q
self.mcu = mcu
self.sets = setCallback
self.mac = mac
self.lock = threading.Lock()
self.updateState = state
self.SAT_COM, self.reconnecting = self.updateState()
line = self.mac
n = 2
macList = [line[i:i+n] for i in range(0, len(line), n)]
self.zigMac = ""
for i in macList:
self.zigMac = self.zigMac + i.lower() + ":"
#wait 15 seconds to make sure the 3g didn't work
time.sleep(15)
self.SAT_COM, self.reconnecting = self.updateState()
self.conType = None
while self.SAT_COM == False and self.reconnecting == True:
self.SAT_COM, self.reconnecting = self.updateState()
self.conType = self.connectSerail()
if self.conType != None:
break
try:
self.ser.open
time.sleep(2)
self.ser.flushInput() #flush input buffer, discarding all its contents
self.ser.flushOutput()#flush output buffer, aborting current output
#start the listening thread
thread.start_new_thread(self.run, ())
#while SAT_COM == False and reconnection == True do a handshake every few hours until something changes, either 3g comes back or you connect to the sats
while self.SAT_COM == False and self.reconnecting == True:
print "sending handshake"
print "SAT COM is"
print self.SAT_COM
time.sleep(3)
self.handshake()
time.sleep(3)
time.sleep(600)
self.SAT_COM, self.reconnecting = self.updateState()
print "handshake done"
print self.SAT_COM
print self.reconnecting
except:
pass
def handshake(self):
data = "hs:" + self.mac
self.send(data)
def connectSerail(self):
if self.conType != None:
try:
self.ser.close()
except:
pass
try:
self.ser = serial.Serial(port='/dev/ttyS20', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, xonxoff=False, timeout=1, rtscts=False, dsrdtr=False)
self.ser.write('ATE0' + chr(13))
print "connected on ttsyS2"
return "232"
except:
try:
self.ser = serial.Serial(port='/dev/ttyUSB10', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, xonxoff=False, timeout=1, rtscts=False, dsrdtr=False)
self.ser.write('ATE0' + chr(13))
print "connected on USB0"
return "232"
except:
try:
#set up rs232 for link to DeapSea
ans = False
#make sure the baud rate gets set
while ans == False:
ans = self.mcu.set232Baud(9600)
time.sleep(1)
self.ser = self.mcu.rs232
print "connected on M1 rs232"
time.sleep(1)
self.ser.write('ATE0' + chr(13))
return "M1"
except:
print "couldn't connect to com port for the SAT connection, retrying in 10 sec"
time.sleep(10)
return None
def send(self, input):
with self.lock:
#clear completed messages
self.ser.read(512)
self.ser.write("AT%MGRS" + chr(13))
time.sleep(2)
resp = self.ser.read(512)
print "232 response:"
print resp
if resp == "":
print "reseting 232 interface in send"
self.connectSerail()
#self.mcu.rs232reset()
#self.mcu.set232Baud(9600)
msg = '"AT%MGRT=' + ('"%s",2,129.1,1,"%s"' % (str(binascii.b2a_hex(os.urandom(4))), input))
self.ser.write(msg + chr(13))
time.sleep(2)
#with self.lock:
# input = makePacket(str(input))
#
# #print type(input)
# clear = '04'
# self.ser.write(clear.decode("hex"))
# time.sleep(1)
# self.ser.write(input.decode("hex"))
# time.sleep(2)
def passToSets(self, msg):
#[{"user":"demo@meshify.com","mac":"000CE373293D","company":"188","payload":{"name":"wipom_[00:0c:e3:73:29:3d:00:21]!.do2","value":"1","expires":"1389369695"},"msgId":4478}]
#i need msg id and name and value
#short version will be like this: deviceName/last4ofTech/channel/value/msgid
#the above would be: wipom/0021/do2/1/9898
#build the full name back:
m = msg.split('/')
if m[0] == "main":
name = m[0] + "." + m[2]
else:
name = m[0] + "_[" + self.zigMac + m[1][0:2] + ":" + m[1][2:4] + "]!." + m[2]
#now build the json back:
j = '[{"user":"demo@meshify.com","mac":"%s","company":"1","payload":{"name":"%s","value":"%s","expires":"1389369695"},"msgId":"%s"}]' % (self.mac, name, m[3], m[4])
thread.start_new_thread(self.sets, (j,))
pass
def run(self):
#sleep for 30 seconds on start
time.sleep(30)
#if reconnecting is False, then we are back on 3g, so kill this thread
while self.reconnecting == True:
self.SAT_COM, self.reconnecting = self.updateState()
time.sleep(1)
print "sat looping again"
try:
try:
val = self.q.get(block=False, timeout=1)
except Exception,e:
print "####################"
print "did't get from sat Q"
print e
else:
print "here is the sat Item"
print val
#val[0] = topic val[1] = json val[2] = qos
# meshify/db/188/000CE373293D/wipom_[00:0c:e3:73:29:3d:00:21]!/ai1
#[ { "value":"0", "timestamp":"1422962934" } ]
#send format will be: deviceName/last4ofTech/channel/value
#example: wipom/0021/do2/1
#response: value/id
if val[0].split('/')[1] == "responses":
value = eval(val[1])[0]['value']
id = eval(val[1])[0]['msgId']
data = str(value) + "/" + str(id)
else:
a = val[0].split('/')
channel = a[5]
deviceName = a[4].split('_')[0]
last4 = a[4].split('_')[1].replace(':', '').replace(']!', '')[-4:]
val = eval(val[1])[0]['value']
data = deviceName + "/" + str(last4) + "/" + channel + "/" + str(val)
print "sending up data"
print data
self.send(data)
pass
with self.lock:
#clear out the read data
self.ser.read(512)
self.ser.write("AT%MGFN" + chr(13))
time.sleep(2)
h = self.ser.read(512)
print "232 response:"
print h
if h == "":
print "reseting 232 interface in main loop"
self.connectSerail()
#self.mcu.rs232reset()
#self.mcu.set232Baud(9600)
continue
h = h.replace("\r\n%MGFN: ", "")
h = h.replace("\r\n\r\nOK\r\n", "")
h = h.split("\r\n")
lst = []
for i in h:
lst.append(i.split(",")[0].replace('"', ""))
for item in lst:
#clear out data line
self.ser.read(512)
self.ser.write('AT%MGFG="' + item + '",1' + chr(13))
time.sleep(2)
str1 = self.ser.read(512)
print "232 response:"
print str1
if str1.split(",")[3] == "129":
print "we have a match"
msg = str1.split(",")[7].split('"')[1].replace("\\01", "")
if msg == 'reg':
thread.start_new_thread(self.handshake, ())
else:
thread.start_new_thread(self.passToSets, (msg,))
"""
response = self.ser.read(2048)
#print response
try:
line = response.encode('hex')
#print line
lst = makeList(line)
for i in lst:
i = unEscape(i)
# print i
if i[8:12] == "d507":
#print "we have a new message!!"
#print "the length is:"
l = int(('0x' + i[36:40]), 16)
#print l
print "message is:"
msg = i[40: (40 + (l * 2))]
print msg.decode("hex")
if msg.decode("hex") == 'reg':
self.handshake()
else:
self.passToSets(msg.decode("hex"))"""
except Exception,e:
print "####################"
print e
print "big loop failed on Sat RUN"
self.send('unreg')
def makePacket(msg):
#this function takes in any ascii string and packages it into a hex string to be sent to the modem, it returns a string of hex characters
print"making message"
print msg
hexstr = '0x03'
#first get crc
#the length of the message will be the length of the message + 4 bytes
msgLen = len(msg)
msgLen = format(msgLen, '#06x')
msgLen = str(msgLen)
msgPart1 = msgLen[:4]
msgPart2 = '0x' + msgLen[-2:]
#print msgPart1, msgPart2
packetLen = len(msg) + 22
#print packetLen
packetLen = format(packetLen, '#06x')
packetLen = str(packetLen)
part1 = packetLen[:4]
part2 = '0x' + packetLen[-2:]
sum1 = 0x03 + int(part1, 16) + int(part2, 16) + 0xC5 + 0xC2 + 0x00 + 0x00 + 0x00 + 0x00 + 0xC0 + 0x00 + 0x00 + 0x00 + 0x00 + 0x02 + 0x58 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + int(msgPart1, 16) + int(msgPart2, 16)
#print sum1
#print part1, part2
packetLen = packetLen.replace('0x', '')
#print packetLen
sum2 = 0x00
for i in array.array('B', msg):
char = hex(i)
#print char
sum2 += int(char, 16)
crc = 0xFFFF - (sum1 + sum2)
#print crc
#print hex(crc)
list = '03' + part1.replace('0x', '') + part2.replace('0x', '') + 'c5c200000000c000000000025800000000000000' + msgPart1.replace('0x', '') + msgPart2.replace('0x', '')
#print list
for i in array.array('B', msg):
char = str(hex(i)).replace('0x', '')
list += char
list += str(format(crc, '#06x')).replace('0x', '')
#here are data is complete without the beginning 01 and end 04, so we can escape characters now
list = escape(list)
list = '01' + list + '04'
#print list
return list
def escape(line):
#escape characters
n = 2
line = [line[i:i+n] for i in range(0, len(line), n)]
#print line
for i in range(len(line)):
if line[i] == "01":
line[i] = "1021"
elif line[i] == "04":
line[i] = "1024"
elif line[i] == "10":
line[i] = "1030"
elif line[i] == "11":
line[i] = "1031"
elif line[i] == "13":
line[i] = "1033"
newData = ""
#print line
for i in line:
#print i
newData += str(i)
#print "here is the new list"
#print newData
return newData
def unEscape(line):
#unescape characters
n = 2
line = [line[i:i+n] for i in range(0, len(line), n)]
#print line
for i in range(len(line)):
if line[i] == "10":
#print "found a 10"
if line[i + 1] == "21":
line[i] = "01"
line[i + 1] = ""
elif line[i + 1] == "24":
line[i] = "04"
line[i + 1] = ""
elif line[i + 1] == "30":
line[i] = "10"
line[i + 1] = ""
elif line[i + 1] == "31":
line[i] = "11"
line[i + 1] = ""
elif line[i + 1] == "33":
line[i] = "13"
line[i + 1] = ""
newData = ""
#print line
for i in line:
#print i
newData += str(i)
#print "here is the new list"
#print newData
return newData
def makeList(line):
lst = []
#here we will take in a bunch of serial data and make a list of individual responses from the modem
n = 2
line = [line[i:i+n] for i in range(0, len(line), n)]
localLine = ""
for i in line:
localLine += i
if i == "04":
lst.append(localLine)
localLine = ""
return lst
"""
#sum1 = (0x03 + 0x00 + 0x1b + 0xC5 + 0xC2 + 0x00 + 0x00 + 0x00 + 0x00 + 0xC0 + 0x00 + 0x00 + 0x00 + 0x00 + 0x02 + 0x58 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x05 + 0x68 + 0x65 + 0x6c + 0x6c + 0x6f )
#crc = 0xfb27
#input = '01030006C682102105103020FE7804'
#print type(input)
input = makePacket('lewis is cool')
print type(input)
#input = '0103001bc5c200000000c000000000025800000000000000000568656c6c6ffb2704'
#data = data.decode('hex')
#for i in array.array('B', "hello")
ser = serial.Serial(port='/dev/tty.usbserial', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, xonxoff=False, timeout=2, rtscts=False, dsrdtr=False, interCharTimeout=.05)
ser.open
time.sleep(2)
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
#ser.sendBreak(duration=0.25)
#time.sleep(1)
#ser.write(input.decode("hex"))
#print "sending",input.decode("hex")
clear = '04'
ser.write(clear.decode("hex"))
time.sleep(1)
ser.write(input.decode("hex"))
time.sleep(2)
while True:
time.sleep(1)
response = ser.read(2048)
print response
try:
line = response.encode('hex')
print line
lst = makeList(line)
for i in lst:
i = unEscape(i)
print i
if i[8:12] == "d507":
print "we have a new message!!"
print "the length is:"
l = int(('0x' + i[36:40]), 16)
print l
print "message is:"
msg = i[40: (40 + (l * 2))]
print msg.decode("hex")
except:
print "didn't work on hex :("
ser.close()
"""