Added tank and fuel sensor types. Added basic renderer for proximity, gravity, magnetics and angular velocity.

This commit is contained in:
Mark Qvist 2024-06-01 12:08:09 +02:00
parent 4c9de8b184
commit 971a207582
2 changed files with 284 additions and 5 deletions

View File

@ -53,7 +53,7 @@ class Telemeter():
Sensor.SID_PROXIMITY: Proximity, Sensor.SID_POWER_CONSUMPTION: PowerConsumption, Sensor.SID_PROXIMITY: Proximity, Sensor.SID_POWER_CONSUMPTION: PowerConsumption,
Sensor.SID_POWER_PRODUCTION: PowerProduction, Sensor.SID_PROCESSOR: Processor, Sensor.SID_POWER_PRODUCTION: PowerProduction, Sensor.SID_PROCESSOR: Processor,
Sensor.SID_RAM: RandomAccessMemory, Sensor.SID_NVM: NonVolatileMemory, Sensor.SID_RAM: RandomAccessMemory, Sensor.SID_NVM: NonVolatileMemory,
Sensor.SID_CUSTOM: Custom, Sensor.SID_CUSTOM: Custom, Sensor.SID_TANK: Tank, Sensor.SID_FUEL: Fuel,
} }
self.available = { self.available = {
"time": Sensor.SID_TIME, "time": Sensor.SID_TIME,
@ -66,7 +66,7 @@ class Telemeter():
"acceleration": Sensor.SID_ACCELERATION, "proximity": Sensor.SID_PROXIMITY, "acceleration": Sensor.SID_ACCELERATION, "proximity": Sensor.SID_PROXIMITY,
"power_consumption": Sensor.SID_POWER_CONSUMPTION, "power_production": Sensor.SID_POWER_PRODUCTION, "power_consumption": Sensor.SID_POWER_CONSUMPTION, "power_production": Sensor.SID_POWER_PRODUCTION,
"processor": Sensor.SID_PROCESSOR, "ram": Sensor.SID_RAM, "nvm": Sensor.SID_NVM, "processor": Sensor.SID_PROCESSOR, "ram": Sensor.SID_RAM, "nvm": Sensor.SID_NVM,
"custom": Sensor.SID_CUSTOM "custom": Sensor.SID_CUSTOM, "tank": Sensor.SID_TANK, "fuel": Sensor.SID_FUEL
} }
self.from_packed = from_packed self.from_packed = from_packed
self.sensors = {} self.sensors = {}
@ -193,6 +193,8 @@ class Sensor():
SID_PROCESSOR = 0x13 SID_PROCESSOR = 0x13
SID_RAM = 0x14 SID_RAM = 0x14
SID_NVM = 0x15 SID_NVM = 0x15
SID_TANK = 0x16
SID_FUEL = 0x17
SID_CUSTOM = 0xff SID_CUSTOM = 0xff
def __init__(self, sid = None, stale_time = None): def __init__(self, sid = None, stale_time = None):
@ -1080,6 +1082,17 @@ class MagneticField(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "magnet",
"name": "Magnetic Field",
"values": { "x": self.data["x"], "y": self.data["y"], "z": self.data["z"] },
}
return rendered
class AmbientLight(Sensor): class AmbientLight(Sensor):
SID = Sensor.SID_AMBIENT_LIGHT SID = Sensor.SID_AMBIENT_LIGHT
STALE_TIME = 1 STALE_TIME = 1
@ -1192,6 +1205,17 @@ class Gravity(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "arrow-down-thin-circle-outline",
"name": "Gravity",
"values": { "x": self.data["x"], "y": self.data["y"], "z": self.data["z"] },
}
return rendered
class AngularVelocity(Sensor): class AngularVelocity(Sensor):
SID = Sensor.SID_ANGULAR_VELOCITY SID = Sensor.SID_ANGULAR_VELOCITY
STALE_TIME = 1 STALE_TIME = 1
@ -1238,6 +1262,17 @@ class AngularVelocity(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "orbit",
"name": "Angular Velocity",
"values": { "x": self.data["x"], "y": self.data["y"], "z": self.data["z"] },
}
return rendered
class Acceleration(Sensor): class Acceleration(Sensor):
SID = Sensor.SID_ACCELERATION SID = Sensor.SID_ACCELERATION
STALE_TIME = 1 STALE_TIME = 1
@ -1329,6 +1364,17 @@ class Proximity(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "signal-distance-variant",
"name": "Proximity",
"values": { "triggered": self.data },
}
return rendered
class PowerConsumption(Sensor): class PowerConsumption(Sensor):
SID = Sensor.SID_POWER_CONSUMPTION SID = Sensor.SID_POWER_CONSUMPTION
STALE_TIME = 5 STALE_TIME = 5
@ -1835,3 +1881,190 @@ class Custom(Sensor):
} }
return rendered return rendered
class Tank(Sensor):
SID = Sensor.SID_TANK
STALE_TIME = 5
def __init__(self):
super().__init__(type(self).SID, type(self).STALE_TIME)
def setup_sensor(self):
self.update_data()
def teardown_sensor(self):
self.data = None
def update_entry(self, capacity=0, level=0, unit=None, type_label=None, custom_icon=None):
if type_label == None:
type_label = 0x00
elif type(type_label) != str:
return False
if unit != None and type(unit) != str:
return False
if self.data == None:
self.data = {}
self.data[type_label] = [capacity, level, unit, custom_icon]
return True
def remove_entry(self, type_label=None):
if type_label == None:
type_label = 0x00
if type_label in self.data:
self.data.pop(type_label)
return True
return False
def update_data(self):
pass
def pack(self):
d = self.data
if d == None:
return None
else:
packed = []
for type_label in self.data:
packed.append([type_label, self.data[type_label]])
return packed
def unpack(self, packed):
try:
if packed == None:
return None
else:
unpacked = {}
for entry in packed:
unpacked[entry[0]] = entry[1]
return unpacked
except:
return None
def render(self, relative_to=None):
if self.data == None:
return None
entries = []
for type_label in self.data:
if type_label == 0x00:
label = "Tank"
else:
label = type_label
set_unit = self.data[type_label][2] if self.data[type_label][2] != None else "L"
entries.append({
"label": label,
"unit": set_unit,
"capacity": self.data[type_label][0],
"level": self.data[type_label][1],
"free": self.data[type_label][0]-self.data[type_label][1],
"percent": (self.data[type_label][1]/self.data[type_label][0])*100,
"custom_icon": self.data[type_label][3],
})
rendered = {
"icon": "storage-tank",
"name": "Tank",
"values": entries,
}
return rendered
class Fuel(Sensor):
SID = Sensor.SID_FUEL
STALE_TIME = 5
def __init__(self):
super().__init__(type(self).SID, type(self).STALE_TIME)
def setup_sensor(self):
self.update_data()
def teardown_sensor(self):
self.data = None
def update_entry(self, capacity=0, level=0, unit=None, type_label=None, custom_icon=None):
if type_label == None:
type_label = 0x00
elif type(type_label) != str:
return False
if unit != None and type(unit) != str:
return False
if self.data == None:
self.data = {}
self.data[type_label] = [capacity, level, unit, custom_icon]
return True
def remove_entry(self, type_label=None):
if type_label == None:
type_label = 0x00
if type_label in self.data:
self.data.pop(type_label)
return True
return False
def update_data(self):
pass
def pack(self):
d = self.data
if d == None:
return None
else:
packed = []
for type_label in self.data:
packed.append([type_label, self.data[type_label]])
return packed
def unpack(self, packed):
try:
if packed == None:
return None
else:
unpacked = {}
for entry in packed:
unpacked[entry[0]] = entry[1]
return unpacked
except:
return None
def render(self, relative_to=None):
if self.data == None:
return None
entries = []
for type_label in self.data:
if type_label == 0x00:
label = "Fuel"
else:
label = type_label
set_unit = self.data[type_label][2] if self.data[type_label][2] != None else "L"
entries.append({
"label": label,
"unit": set_unit,
"capacity": self.data[type_label][0],
"level": self.data[type_label][1],
"free": self.data[type_label][0]-self.data[type_label][1],
"percent": (self.data[type_label][1]/self.data[type_label][0])*100,
"custom_icon": self.data[type_label][3],
})
rendered = {
"icon": "fuel",
"name": "Fuel",
"values": entries,
}
return rendered

View File

@ -312,13 +312,22 @@ class RVDetails(MDRecycleView):
"Ambient Temperature": 40, "Ambient Temperature": 40,
"Relative Humidity": 50, "Relative Humidity": 50,
"Ambient Pressure": 60, "Ambient Pressure": 60,
"Magnetic Field": 61,
"Gravity": 62,
"Angular Velocity": 63,
"Acceleration": 64,
"Proximity": 65,
"Battery": 70, "Battery": 70,
"Processor": 72, "Processor": 72,
"Random Access Memory": 74, "Random Access Memory": 74,
"Non-Volatile Memory": 76, "Non-Volatile Memory": 76,
"Timestamp": 80, "Power Consumption": 80,
"Custom": 85, "Power Production": 81,
"Received": 90, "Tank": 90,
"Fuel": 91,
"Custom": 100,
"Timestamp": 190,
"Received": 200,
} }
def pass_job(sender=None): def pass_job(sender=None):
@ -326,6 +335,8 @@ class RVDetails(MDRecycleView):
self.entries = [] self.entries = []
rendered_telemetry.sort(key=lambda s: sort[s["name"]] if s["name"] in sort else 1000) rendered_telemetry.sort(key=lambda s: sort[s["name"]] if s["name"] in sort else 1000)
RNS.log("Sorted:")
RNS.log(str(rendered_telemetry))
for s in rendered_telemetry: for s in rendered_telemetry:
try: try:
extra_entries = [] extra_entries = []
@ -532,6 +543,38 @@ class RVDetails(MDRecycleView):
e_text = f"{label} [b]{value}[/b]" e_text = f"{label} [b]{value}[/b]"
extra_entries.append({"icon": set_icon, "text": e_text}) extra_entries.append({"icon": set_icon, "text": e_text})
elif name == "Tank":
cs = s["values"]
if cs != None:
for c in cs:
label = c["label"]
cicon = c["custom_icon"]
unit = c["unit"]
cap = round(c["capacity"], 1)
lvl = round(c["level"], 1)
free = round(c["free"], 1)
pct = round(c["percent"], 1)
set_icon = cicon if cicon else s["icon"]
e_text = f"{label} level is [b]{lvl} {unit}[/b] ([b]{pct}%[/b])"
extra_entries.append({"icon": set_icon, "text": e_text})
elif name == "Fuel":
cs = s["values"]
if cs != None:
for c in cs:
label = c["label"]
cicon = c["custom_icon"]
unit = c["unit"]
cap = round(c["capacity"], 1)
lvl = round(c["level"], 1)
free = round(c["free"], 1)
pct = round(c["percent"], 1)
set_icon = cicon if cicon else s["icon"]
e_text = f"{label} level is [b]{lvl} {unit}[/b] ([b]{pct}%[/b])"
extra_entries.append({"icon": set_icon, "text": e_text})
elif name == "Processor": elif name == "Processor":
cs = s["values"] cs = s["values"]
if cs != None: if cs != None:
@ -711,6 +754,9 @@ class RVDetails(MDRecycleView):
if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None: if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None:
d = s["deltas"][dt] d = s["deltas"][dt]
formatted_values += f" (Δ = {d} {vn})" formatted_values += f" (Δ = {d} {vn})"
formatted_values += ", "
formatted_values = formatted_values[:-2]
data = None data = None
if formatted_values != None: if formatted_values != None: