Added periodic ID option to RNode interface. Fixed RNode SNR stat indication.
This commit is contained in:
parent
0140cd6eba
commit
8c2cfb0349
@ -70,7 +70,9 @@ class RNodeInterface(Interface):
|
|||||||
RSSI_OFFSET = 157
|
RSSI_OFFSET = 157
|
||||||
SNR_OFFSET = 128
|
SNR_OFFSET = 128
|
||||||
|
|
||||||
def __init__(self, owner, name, port, frequency = None, bandwidth = None, txpower = None, sf = None, cr = None, flow_control = False):
|
CALLSIGN_MAX_LEN = 32
|
||||||
|
|
||||||
|
def __init__(self, owner, name, port, frequency = None, bandwidth = None, txpower = None, sf = None, cr = None, flow_control = False, id_interval = None, id_callsign = None):
|
||||||
self.serial = None
|
self.serial = None
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -90,6 +92,8 @@ class RNodeInterface(Interface):
|
|||||||
self.state = KISS.RADIO_STATE_OFF
|
self.state = KISS.RADIO_STATE_OFF
|
||||||
self.bitrate = 0
|
self.bitrate = 0
|
||||||
|
|
||||||
|
self.last_id = 0
|
||||||
|
|
||||||
self.r_frequency = None
|
self.r_frequency = None
|
||||||
self.r_bandwidth = None
|
self.r_bandwidth = None
|
||||||
self.r_txpower = None
|
self.r_txpower = None
|
||||||
@ -123,10 +127,22 @@ class RNodeInterface(Interface):
|
|||||||
RNS.log("Invalid spreading factor configured for "+str(self), RNS.LOG_ERROR)
|
RNS.log("Invalid spreading factor configured for "+str(self), RNS.LOG_ERROR)
|
||||||
self.validcfg = False
|
self.validcfg = False
|
||||||
|
|
||||||
if (self.cr < 5 or self.sf > 8):
|
if (self.cr < 5 or self.cr > 8):
|
||||||
RNS.log("Invalid coding rate configured for "+str(self), RNS.LOG_ERROR)
|
RNS.log("Invalid coding rate configured for "+str(self), RNS.LOG_ERROR)
|
||||||
self.validcfg = False
|
self.validcfg = False
|
||||||
|
|
||||||
|
if id_interval != None and id_callsign != None:
|
||||||
|
if (len(id_callsign.encode("utf-8")) <= RNodeInterface.CALLSIGN_MAX_LEN):
|
||||||
|
self.should_id = True
|
||||||
|
self.id_callsign = id_callsign
|
||||||
|
self.id_interval = id_interval
|
||||||
|
else:
|
||||||
|
RNS.log("The encoded ID callsign for "+str(self)+" exceeds the max length of "+str(RNodeInterface.CALLSIGN_MAX_LEN)+" bytes.", RNS.LOG_ERROR)
|
||||||
|
self.validcfg = False
|
||||||
|
else:
|
||||||
|
self.id_interval = None
|
||||||
|
self.id_callsign = None
|
||||||
|
|
||||||
if (not self.validcfg):
|
if (not self.validcfg):
|
||||||
raise ValueError("The configuration for "+str(self)+" contains errors, interface is offline")
|
raise ValueError("The configuration for "+str(self)+" contains errors, interface is offline")
|
||||||
|
|
||||||
@ -259,7 +275,7 @@ class RNodeInterface(Interface):
|
|||||||
try:
|
try:
|
||||||
self.bitrate = self.r_sf * ( (4.0/self.cr) / (math.pow(2,self.r_sf)/(self.r_bandwidth/1000)) ) * 1000
|
self.bitrate = self.r_sf * ( (4.0/self.cr) / (math.pow(2,self.r_sf)/(self.r_bandwidth/1000)) ) * 1000
|
||||||
self.bitrate_kbps = round(self.bitrate/1000.0, 2)
|
self.bitrate_kbps = round(self.bitrate/1000.0, 2)
|
||||||
RNS.log(str(self)+" On-air bitrate is now "+str(self.bitrate_kbps)+ " kbps", RNS.LOG_DEBUG)
|
RNS.log(str(self)+" On-air bitrate is now "+str(self.bitrate_kbps)+ " kbps", RNS.LOG_INFO)
|
||||||
except:
|
except:
|
||||||
self.bitrate = 0
|
self.bitrate = 0
|
||||||
|
|
||||||
@ -273,9 +289,17 @@ class RNodeInterface(Interface):
|
|||||||
if self.flow_control:
|
if self.flow_control:
|
||||||
self.interface_ready = False
|
self.interface_ready = False
|
||||||
|
|
||||||
data = KISS.escape(data)
|
frame = b""
|
||||||
frame = bytes([0xc0])+bytes([0x00])+data+bytes([0xc0])
|
|
||||||
|
if self.id_interval != None and self.id_callsign != None:
|
||||||
|
if self.last_id + self.id_interval < time.time():
|
||||||
|
self.last_id = time.time()
|
||||||
|
frame = bytes([0xc0])+bytes([0x00])+KISS.escape(self.id_callsign.encode("utf-8"))+bytes([0xc0])
|
||||||
|
|
||||||
|
data = KISS.escape(data)
|
||||||
|
frame += bytes([0xc0])+bytes([0x00])+data+bytes([0xc0])
|
||||||
written = self.serial.write(frame)
|
written = self.serial.write(frame)
|
||||||
|
|
||||||
if written != len(frame):
|
if written != len(frame):
|
||||||
raise IOError("Serial interface only wrote "+str(written)+" bytes of "+str(len(data)))
|
raise IOError("Serial interface only wrote "+str(written)+" bytes of "+str(len(data)))
|
||||||
else:
|
else:
|
||||||
@ -408,7 +432,7 @@ class RNodeInterface(Interface):
|
|||||||
elif (command == KISS.CMD_STAT_RSSI):
|
elif (command == KISS.CMD_STAT_RSSI):
|
||||||
self.r_stat_rssi = byte-RNodeInterface.RSSI_OFFSET
|
self.r_stat_rssi = byte-RNodeInterface.RSSI_OFFSET
|
||||||
elif (command == KISS.CMD_STAT_SNR):
|
elif (command == KISS.CMD_STAT_SNR):
|
||||||
self.r_stat_snr = byte-RNodeInterface.SNR_OFFSET
|
self.r_stat_snr = int.from_bytes(bytes([byte]), byteorder="big", signed=True) * 0.25
|
||||||
elif (command == KISS.CMD_RANDOM):
|
elif (command == KISS.CMD_RANDOM):
|
||||||
self.r_random = byte
|
self.r_random = byte
|
||||||
elif (command == KISS.CMD_ERROR):
|
elif (command == KISS.CMD_ERROR):
|
||||||
|
@ -248,8 +248,7 @@ class Reticulum:
|
|||||||
txtail = int(c["txtail"]) if "txtail" in c else None
|
txtail = int(c["txtail"]) if "txtail" in c else None
|
||||||
persistence = int(c["persistence"]) if "persistence" in c else None
|
persistence = int(c["persistence"]) if "persistence" in c else None
|
||||||
slottime = int(c["slottime"]) if "slottime" in c else None
|
slottime = int(c["slottime"]) if "slottime" in c else None
|
||||||
flow_control = (True if c["flow_control"] == "true" else False) if "flow_control" in c else False
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
|
||||||
port = c["port"] if "port" in c else None
|
port = c["port"] if "port" in c else None
|
||||||
speed = int(c["speed"]) if "speed" in c else 9600
|
speed = int(c["speed"]) if "speed" in c else 9600
|
||||||
databits = int(c["databits"]) if "databits" in c else 8
|
databits = int(c["databits"]) if "databits" in c else 8
|
||||||
@ -286,8 +285,7 @@ class Reticulum:
|
|||||||
txtail = int(c["txtail"]) if "txtail" in c else None
|
txtail = int(c["txtail"]) if "txtail" in c else None
|
||||||
persistence = int(c["persistence"]) if "persistence" in c else None
|
persistence = int(c["persistence"]) if "persistence" in c else None
|
||||||
slottime = int(c["slottime"]) if "slottime" in c else None
|
slottime = int(c["slottime"]) if "slottime" in c else None
|
||||||
flow_control = (True if c["flow_control"] == "true" else False) if "flow_control" in c else False
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
|
||||||
port = c["port"] if "port" in c else None
|
port = c["port"] if "port" in c else None
|
||||||
speed = int(c["speed"]) if "speed" in c else 9600
|
speed = int(c["speed"]) if "speed" in c else 9600
|
||||||
databits = int(c["databits"]) if "databits" in c else 8
|
databits = int(c["databits"]) if "databits" in c else 8
|
||||||
@ -330,7 +328,9 @@ class Reticulum:
|
|||||||
txpower = int(c["txpower"]) if "txpower" in c else None
|
txpower = int(c["txpower"]) if "txpower" in c else None
|
||||||
spreadingfactor = int(c["spreadingfactor"]) if "spreadingfactor" in c else None
|
spreadingfactor = int(c["spreadingfactor"]) if "spreadingfactor" in c else None
|
||||||
codingrate = int(c["codingrate"]) if "codingrate" in c else None
|
codingrate = int(c["codingrate"]) if "codingrate" in c else None
|
||||||
flow_control = (True if c["flow_control"] == "true" else False) if "flow_control" in c else False
|
flow_control = c.as_bool("flow_control") if "flow_control" in c else False
|
||||||
|
id_interval = int(c["id_interval"]) if "id_interval" in c else None
|
||||||
|
id_callsign = c["id_callsign"] if "id_callsign" in c else None
|
||||||
|
|
||||||
port = c["port"] if "port" in c else None
|
port = c["port"] if "port" in c else None
|
||||||
|
|
||||||
@ -341,11 +341,14 @@ class Reticulum:
|
|||||||
RNS.Transport,
|
RNS.Transport,
|
||||||
name,
|
name,
|
||||||
port,
|
port,
|
||||||
frequency,
|
frequency = frequency,
|
||||||
bandwidth,
|
bandwidth = bandwidth,
|
||||||
txpower,
|
txpower = txpower,
|
||||||
spreadingfactor,
|
sf = spreadingfactor,
|
||||||
flow_control
|
cr = codingrate,
|
||||||
|
flow_control = flow_control,
|
||||||
|
id_interval = id_interval,
|
||||||
|
id_callsign = id_callsign
|
||||||
)
|
)
|
||||||
|
|
||||||
if "outgoing" in c and c["outgoing"].lower() == "true":
|
if "outgoing" in c and c["outgoing"].lower() == "true":
|
||||||
@ -355,7 +358,7 @@ class Reticulum:
|
|||||||
|
|
||||||
RNS.Transport.interfaces.append(interface)
|
RNS.Transport.interfaces.append(interface)
|
||||||
else:
|
else:
|
||||||
RNS.log("Skipping disabled interface \""+name+"\"", RNS.LOG_VERBOSE)
|
RNS.log("Skipping disabled interface \""+name+"\"", RNS.LOG_NOTICE)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("The interface \""+name+"\" could not be created. Check your configuration file for errors!", RNS.LOG_ERROR)
|
RNS.log("The interface \""+name+"\" could not be created. Check your configuration file for errors!", RNS.LOG_ERROR)
|
||||||
@ -533,6 +536,19 @@ loglevel = 4
|
|||||||
# fastest, and 8 the longest range.
|
# fastest, and 8 the longest range.
|
||||||
codingrate = 5
|
codingrate = 5
|
||||||
|
|
||||||
|
# You can configure the RNode to send
|
||||||
|
# out identification on the channel with
|
||||||
|
# a set interval by configuring the
|
||||||
|
# following two parameters. The trans-
|
||||||
|
# ceiver will only ID before making an
|
||||||
|
# actual transmission, and if the set
|
||||||
|
# interval has elapsed since it's last
|
||||||
|
# ID. Interval is configured in seconds
|
||||||
|
# This option is commented out and not
|
||||||
|
# used by default.
|
||||||
|
# id_callsign = MYCALL-0
|
||||||
|
# id_interval = 600
|
||||||
|
|
||||||
|
|
||||||
# An example KISS modem interface. Useful for running
|
# An example KISS modem interface. Useful for running
|
||||||
# Reticulum over packet radio hardware.
|
# Reticulum over packet radio hardware.
|
||||||
|
Loading…
Reference in New Issue
Block a user