forked from ve3sjk/SkyWeather-Python-3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadLoRa.py
executable file
·273 lines (261 loc) · 13.9 KB
/
readLoRa.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#!/usb/bin/env python
import sys
import os
import time
import array
import state
import struct
import util
import crcpython2
import traceback
import updateBlynk
try:
import conflocal as config
except ImportError:
import config
WXLINKPROTOCOLID = 3
# change this if you have changed the SolarMAX protocol number 8 is for SolarMAX Lipo and 10 is for SolarMAX LeadAcid
if(config.SolarMAX_Type == "LEAD"):
SOLARMAXPROTOCOL = 10
else:
SOLARMAXPROTOCOL = 8
# read WXLink and return list to set variables
crcCalc = crcpython2.CRCCCITT(version='XModem')
def readWXLink(block1, block2, stringblock1, stringblock2, block1_orig, block2_orig):
if (config.SWDEBUG):
print ("Starting readWXLink")
#oldblock1 = block1
#oldblock2 = block2
try:
if ((len(block1) > 0) and (len(block2) > 0)):
# check crc for errors - don't update data if crc is bad
if (config.SWDEBUG):
print ("block1 length=", len(block1))
print ("block2 length=", len(block2))
#get crc from data
receivedCRC = struct.unpack('H', str(block2[29:31]))[0]
#swap bytes for receivedCRC
receivedCRC = (((receivedCRC)>>8) | ((receivedCRC&0xFF)<<8))&0xFFFF
if (config.SWDEBUG):
print ("ReversedreceivedCRC= %x" % receivedCRC)
print ("length of stb1+sb2=", len(stringblock1+stringblock2))
print (''.join('{:02x}'.format(ord(x)) for x in stringblock1))
print (''.join('{:02x}'.format(ord(x)) for x in stringblock2))
calculatedCRC = crcCalc.calculate(block1+block2[0:27])
if (config.SWDEBUG):
print ("calculatedCRC = %x " % calculatedCRC)
# check for start bytes, if not present, then invalidate CRC
if (block1[0] != 0xAB) or (block1[1] != 0x66):
calculatedCRC = receivedCRC + 1
if (receivedCRC == calculatedCRC):
if (config.SWDEBUG):
print ("Good CRC Recived")
# read protocol
protocol_byte = block1[2]
#protocol_byte = struct.unpack('B', str(block1[2:2]))[0]
protocol_ID = protocol_byte / 10
protocol_software_version = protocol_byte - protocol_ID*10
if (config.SWDEBUG):
print("protocol_ID = ", protocol_ID)
print("protocol_software_version = ", protocol_software_version)
# if protocol_ID == 3, then
# use if: SolarMAX_Present == False or Dual_MAX_WXLink == True
if ((protocol_ID == WXLINKPROTOCOLID) and ((config.SolarMAX_Present == False) or (config.Dual_MAX_WXLink == True))): # 3 is the WXLink Protocol
print("protocol %d - WXLink received "% WXLINKPROTOCOLID)
currentWindSpeed = struct.unpack('f', str(block1[9:13]))[0]
currentWindGust = 0.0 # not implemented in Solar WXLink version
totalRain = struct.unpack('l', str(block1[17:21]))[0]
if (config.SWDEBUG):
print("Rain Total=\t%0.2f in")%(totalRain/25.4)
print("Wind Speed=\t%0.2f MPH")%(currentWindSpeed/1.6)
currentWindDirection = struct.unpack('H', str(block1[7:9]))[0]
if (config.SWDEBUG):
print ("Wind Direction=\t\t\t %i Degrees" % currentWindDirection)
# now do the AM2315 Temperature
temperature = struct.unpack('f', str(block1[25:29]))[0]
if (config.SWDEBUG):
print ("OTFloat=%x%x%x%x" %(block1[25], block1[26], block1[27], block1[28]))
elements = [block1[29], block1[30], block1[31], block2[0]]
outHByte = bytearray(elements)
humidity = struct.unpack('f', str(outHByte))[0]
if (config.SWDEBUG):
print ("AM2315 from WXLink temperature: %0.1fC" % temperature)
print ("AM2315 from WXLink humidity: %0.1f%%" % humidity)
# now read the SunAirPlus Data from WXLink
WXbatteryVoltage = struct.unpack('f', str(block2[1:5]))[0]
WXbatteryCurrent = -struct.unpack('f', str(block2[5:9]))[0]
WXloadCurrent = struct.unpack('f', str(block2[9:13]))[0]
WXsolarPanelVoltage = struct.unpack('f', str(block2[13:17]))[0]
WXsolarPanelCurrent = struct.unpack('f', str(block2[17:21]))[0]
WXbatteryPower = WXbatteryVoltage * (WXbatteryCurrent/1000)
WXsolarPower = WXsolarPanelVoltage * (WXsolarPanelCurrent/1000)
WXloadPower = 5.0 * (WXloadCurrent/1000)
WXbatteryCharge = util.returnPercentLeftInBattery(WXbatteryVoltage, 4.19)
state.WXbatteryVoltage = WXbatteryVoltage
state.WXbatteryCurrent = WXbatteryCurrent
state.WXloadCurrent = WXloadCurrent
state.WXsolarVoltage = WXsolarPanelVoltage
state.WXsolarCurrent = WXsolarPanelCurrent
state.WXbatteryPower = WXbatteryPower
state.WXsolarPower = WXsolarPower
state.WXloadPower = WXloadPower
state.WXbatteryCharge = WXbatteryCharge
auxA = struct.unpack('f', str(block2[21:25]))[0]
# now set state variables
if (config.SWDEBUG):
print ("WXLink batteryVoltage = %6.2f" % WXbatteryVoltage)
print ("WXLink batteryCurrent = %6.2f" % WXbatteryCurrent)
print ("WXLink loadCurrent = %6.2f" % WXloadCurrent)
print ("WXLink solarPanelVoltage = %6.2f" % WXsolarPanelVoltage)
print ("WXLink solarPanelCurrent = %6.2f" % WXsolarPanelCurrent)
print ("WXLink auxA = %6.2f" % auxA)
# message ID
MessageID = struct.unpack('l', str(block2[25:29]))[0]
print ("WXLink Message ID %i" % MessageID)
if (config.WXLink_LastMessageID != MessageID):
config.WXLink_Data_Fresh = True
config.WXLink_LastMessageID = MessageID
if (config.SWDEBUG):
print ("WXLink_Data_Fresh set to True")
#
# use protocol 8 if SolarMAX_Present == True
#if (((protocol_ID == 8) or (protocol_ID == 10))and (config.SolarMAX_Present)):
if ((protocol_ID == SOLARMAXPROTOCOL) and (config.SolarMAX_Present)): # 3 is the WXLink Protocol
############################
############################
############################
############################
#print("protocol 8 or 9 - SolarMAX received")
print("protocol "+str(protocol_ID) +" SolarMAX received")
#print("protocol "+str(SOLARMAXPROTOCOL)+ " SolarMAX received")
############################
############################
############################
############################
# now do the inside Temperature in the SolarMAX
SolarMaxInsideTemperature = struct.unpack('f', str(block1[25:29]))[0]
if (config.SWDEBUG):
print ("SMOTFloat=%x%x%x%x" %(block1[25], block1[26], block1[27], block1[28]))
elements = [block1[29], block1[30], block1[31], block2[0]]
outHByte = bytearray(elements)
SolarMaxInsideHumidity = struct.unpack('f', str(outHByte))[0]
if (config.SWDEBUG):
print ("ITemperature from SolarMAX temperature: %0.1fC" % SolarMaxInsideTemperature)
print ("IHumidity from SolarMAX humidity: %0.1f%%" % SolarMaxInsideHumidity)
# now read the SolarMax Data from packet
SolarMaxloadVoltage = struct.unpack('f', str(block1[21:25]))[0]
SolarMaxbatteryVoltage = struct.unpack('f', str(block2[1:5]))[0]
SolarMaxbatteryCurrent = -struct.unpack('f', str(block2[5:9]))[0]
SolarMaxloadCurrent = struct.unpack('f', str(block2[9:13]))[0]
SolarMaxsolarPanelVoltage = struct.unpack('f', str(block2[13:17]))[0]
SolarMaxsolarPanelCurrent = -struct.unpack('f', str(block2[17:21]))[0]
SolarMaxbatteryPower = SolarMaxbatteryVoltage * (SolarMaxbatteryCurrent/1000)
SolarMaxsolarPower = SolarMaxsolarPanelVoltage * (SolarMaxsolarPanelCurrent/1000)
SolarMaxloadPower = SolarMaxloadVoltage * (SolarMaxloadCurrent/1000)
SolarMaxbatteryCharge = util.returnPercentLeftInBattery(SolarMaxbatteryVoltage, 4.19)
state.batteryVoltage = SolarMaxbatteryVoltage
state.batteryCurrent = SolarMaxbatteryCurrent
state.loadCurrent = SolarMaxloadCurrent
state.loadVoltage = SolarMaxloadVoltage
state.solarVoltage = SolarMaxsolarPanelVoltage
state.solarCurrent = SolarMaxsolarPanelCurrent
state.batteryPower = SolarMaxbatteryPower
state.solarPower = SolarMaxsolarPower
state.loadPower = SolarMaxloadPower
state.batteryCharge = SolarMaxbatteryCharge
state.SolarMaxInsideTemperature = SolarMaxInsideTemperature
state.SolarMaxInsideHumidity = SolarMaxInsideHumidity
auxA = struct.unpack('f', str(block2[21:25]))[0]
# now set state variables
if (config.SWDEBUG):
print ("SolarMax batteryVoltage = %6.2f" % SolarMaxbatteryVoltage)
print ("SolarMax batteryCurrent = %6.2f" % SolarMaxbatteryCurrent)
print ("SolarMax loadVoltage = %6.2f" % SolarMaxloadVoltage)
print ("SolarMax loadCurrent = %6.2f" % SolarMaxloadCurrent)
print ("SolarMax solarPanelVoltage = %6.2f" % SolarMaxsolarPanelVoltage)
print ("SolarMax solarPanelCurrent = %6.2f" % SolarMaxsolarPanelCurrent)
print ("SolarMax auxA = %6.2f" % auxA)
# message ID
MessageID = struct.unpack('l', str(block2[25:29]))[0]
print ("SolarMax Message ID %i" % MessageID)
if (config.SolarMAX_Present == True):
if (config.USEBLYNK):
if (config.WXLink_Data_Fresh == True):
if (config.SWDEBUG):
updateBlynk.blynkStatusTerminalUpdate("SolarMAX ID# %d received"%config.WXLink_LastMessageID)
updateBlynk.blynkSolarMAXLine(entry,protocol_ID )
if ((protocol_ID == WXLINKPROTOCOLID) or (protocol_ID == 8) or (protocol_ID == 10)):
#if ((protocol_ID == WXLINKPROTOCOLID) or (protocol_ID == SOLARMAXPROTOCOL) ):
pass
else:
if (config.SWDEBUG):
print ("unknown or non-configured protocol received. Protocol = ", protocol_ID)
return []
else:
print ("Bad CRC Received")
return []
else:
return []
# return list
if ((protocol_ID == WXLINKPROTOCOLID) and ((config.SolarMAX_Present == False) or (config.Dual_MAX_WXLink == True))): # 3 is the WXLink Protocol
returnList = []
returnList.append(protocol_ID)
returnList.append(block1_orig)
returnList.append(block2_orig)
returnList.append(currentWindSpeed)
returnList.append(currentWindGust)
returnList.append(totalRain)
returnList.append(currentWindDirection)
returnList.append(temperature)
returnList.append(humidity)
returnList.append(WXbatteryVoltage)
returnList.append(WXbatteryCurrent)
returnList.append(WXloadCurrent)
returnList.append(WXsolarPanelVoltage)
returnList.append(WXsolarPanelCurrent)
returnList.append(auxA)
returnList.append(MessageID)
else:
returnList = [] # protocol 8 - SolarMAX
returnList.append(protocol_ID)
return returnList
except Exception as e:
if (config.SWDEBUG):
print(traceback.format_exc())
print("LoRa Packet Decode Failure - probably short block receive")
print("e=",e)
return []
def readRawWXLink():
if state.ll.waitRX(timeout=5):
if (config.SWDEBUG):
print("after WXLink waitRX")
data=state.ll.recv()
header=data[0:4]
msg=data[4:]
#print('header: ',header)
#print('message:',array.array('B', msg).tostring())
#for i in range(0,len(data)):
#print('i={:d} {:d} 0x{:X}'.format( i,data[i],data[i]))
if (config.SWDEBUG):
print ("-----------")
block1 = msg[0:32]
if (config.SWDEBUG):
print ("block1=", block1)
block2 = msg[32:65]
state.block1_orig = block1
state.block2_orig = block2
if (config.SWDEBUG):
print ("block2=", block2)
state.stringblock1 = ''.join(chr(e) for e in block1)
state.stringblock2 = ''.join(chr(e) for e in block2[0:27])
if (config.SWDEBUG):
print ("-----------")
print ("block 1")
print (''.join('{:02x}'.format(x) for x in block1))
state.block1 = bytearray(block1)
if (config.SWDEBUG):
print ("block 2")
state.block2 = bytearray(block2)
if (config.SWDEBUG):
print (''.join('{:02x}'.format(x) for x in block2))
print ("-----------")