Skip to content

Commit 01ceb81

Browse files
authored
deleted all the previous commits that were causing problems and added a new commit with better comments (#172)
1 parent 93794b6 commit 01ceb81

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

pyModeS/extra/tcpclient.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pyModeS as pms
77
import traceback
88
import zmq
9+
import math
910

1011

1112
class TcpClient(object):
@@ -149,6 +150,103 @@ def read_beast_buffer(self):
149150
messages.append([msg, ts])
150151
return messages
151152

153+
def read_beast_buffer_rssi_piaware(self):
154+
"""Handle mode-s beast data type.
155+
156+
<esc> "1" : 6 byte MLAT timestamp, 1 byte signal level,
157+
2 byte Mode-AC
158+
<esc> "2" : 6 byte MLAT timestamp, 1 byte signal level,
159+
7 byte Mode-S short frame
160+
<esc> "3" : 6 byte MLAT timestamp, 1 byte signal level,
161+
14 byte Mode-S long frame
162+
<esc> "4" : 6 byte MLAT timestamp, status data, DIP switch
163+
configuration settings (not on Mode-S Beast classic)
164+
<esc><esc>: true 0x1a
165+
<esc> is 0x1a, and "1", "2" and "3" are 0x31, 0x32 and 0x33
166+
167+
timestamp:
168+
wiki.modesbeast.com/Radarcape:Firmware_Versions#The_GPS_timestamp
169+
"""
170+
messages_mlat = []
171+
msg = []
172+
i = 0
173+
174+
# process the buffer until the last divider <esc> 0x1a
175+
# then, reset the self.buffer with the remainder
176+
177+
while i < len(self.buffer):
178+
if self.buffer[i : i + 2] == [0x1A, 0x1A]:
179+
msg.append(0x1A)
180+
i += 1
181+
elif (i == len(self.buffer) - 1) and (self.buffer[i] == 0x1A):
182+
# special case where the last bit is 0x1a
183+
msg.append(0x1A)
184+
elif self.buffer[i] == 0x1A:
185+
if i == len(self.buffer) - 1:
186+
# special case where the last bit is 0x1a
187+
msg.append(0x1A)
188+
elif len(msg) > 0:
189+
messages_mlat.append(msg)
190+
msg = []
191+
else:
192+
msg.append(self.buffer[i])
193+
i += 1
194+
195+
# save the reminder for next reading cycle, if not empty
196+
if len(msg) > 0:
197+
reminder = []
198+
for i, m in enumerate(msg):
199+
if (m == 0x1A) and (i < len(msg) - 1):
200+
# rewind 0x1a, except when it is at the last bit
201+
reminder.extend([m, m])
202+
else:
203+
reminder.append(m)
204+
self.buffer = [0x1A] + msg
205+
else:
206+
self.buffer = []
207+
208+
# extract messages
209+
messages = []
210+
for mm in messages_mlat:
211+
ts = time.time()
212+
213+
msgtype = mm[0]
214+
# print(''.join('%02X' % i for i in mm))
215+
216+
if msgtype == 0x32:
217+
# Mode-S Short Message, 7 byte, 14-len hexstr
218+
msg = "".join("%02X" % i for i in mm[8:15])
219+
elif msgtype == 0x33:
220+
# Mode-S Long Message, 14 byte, 28-len hexstr
221+
msg = "".join("%02X" % i for i in mm[8:22])
222+
else:
223+
# Other message tupe
224+
continue
225+
226+
if len(msg) not in [14, 28]:
227+
continue
228+
229+
'''
230+
we get the raw 0-255 byte value (raw_rssi = mm[7])
231+
we scale it to 0.0 - 1.0 (voltage = raw_rssi / 255)
232+
we convert it to a dBFS power value (rolling the squaring of the voltage into the dB calculation)
233+
'''
234+
235+
df = pms.df(msg)
236+
raw_rssi = mm[7] # eighth byte of Mode-S message should contain RSSI value
237+
rssi_ratio = raw_rssi / 255
238+
signalLevel = rssi_ratio ** 2
239+
dbfs_rssi = 10 * math.log10(signalLevel)
240+
241+
# skip incomplete message
242+
if df in [0, 4, 5, 11] and len(msg) != 14:
243+
continue
244+
if df in [16, 17, 18, 19, 20, 21, 24] and len(msg) != 28:
245+
continue
246+
247+
messages.append([msg, dbfs_rssi, ts])
248+
return messages
249+
152250
def read_skysense_buffer(self):
153251
"""Skysense stream format.
154252

0 commit comments

Comments
 (0)