Implemented telemeter rendering

This commit is contained in:
Mark Qvist 2023-10-24 01:12:32 +02:00
parent bbcb4409e6
commit 3b0f75e9bc
1 changed files with 182 additions and 10 deletions

View File

@ -70,8 +70,9 @@ class Telemeter():
def synthesize(self, sensor): def synthesize(self, sensor):
if sensor in self.available: if sensor in self.available:
if not sensor in self.sensors: if not sensor in self.sensors:
self.sensors[sensor] = self.available[sensor]() self.sensors[sensor] = self.sids[self.available[sensor]]()
self.sensors[sensor].active = True self.sensors[sensor].active = True
self.sensors[sensor].synthesized = True
def enable(self, sensor): def enable(self, sensor):
if not self.from_packed: if not self.from_packed:
@ -87,6 +88,8 @@ class Telemeter():
if sensor in self.sensors: if sensor in self.sensors:
if self.sensors[sensor].active: if self.sensors[sensor].active:
self.sensors[sensor].stop() self.sensors[sensor].stop()
removed = self.sensors.pop(sensor)
del removed
def stop_all(self): def stop_all(self):
if not self.from_packed: if not self.from_packed:
@ -123,6 +126,16 @@ class Telemeter():
packed[self.sensors[sensor].sid] = self.sensors[sensor].pack() packed[self.sensors[sensor].sid] = self.sensors[sensor].pack()
return umsgpack.packb(packed) return umsgpack.packb(packed)
def render(self, relative_to=None):
rendered = []
for sensor in self.sensors:
s = self.sensors[sensor]
if s.active:
r = s.render(relative_to)
if r: rendered.append(r)
return rendered
class Sensor(): class Sensor():
SID_NONE = 0x00 SID_NONE = 0x00
SID_TIME = 0x01 SID_TIME = 0x01
@ -144,6 +157,7 @@ class Sensor():
self._stale_time = stale_time self._stale_time = stale_time
self._data = None self._data = None
self.active = False self.active = False
self.synthesized = False
self.last_update = 0 self.last_update = 0
self.last_read = 0 self.last_read = 0
@ -177,7 +191,8 @@ class Sensor():
raise NotImplementedError() raise NotImplementedError()
def start(self): def start(self):
self.setup_sensor() if not self.synthesized:
self.setup_sensor()
self.active = True self.active = True
def stop(self): def stop(self):
@ -196,6 +211,9 @@ class Sensor():
def unpack(self, packed): def unpack(self, packed):
return packed return packed
def render(self, relative_to=None):
return None
class Time(Sensor): class Time(Sensor):
SID = Sensor.SID_TIME SID = Sensor.SID_TIME
STALE_TIME = 0.1 STALE_TIME = 0.1
@ -228,6 +246,15 @@ class Time(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
rendered = {
"icon": "clock-time-ten-outline",
"name": "Timestamp",
"values": { "UTC": self.data["utc"] },
}
return rendered
class Battery(Sensor): class Battery(Sensor):
SID = Sensor.SID_BATTERY SID = Sensor.SID_BATTERY
STALE_TIME = 10 STALE_TIME = 10
@ -283,7 +310,7 @@ class Battery(Sensor):
is_charging = output['POWER_SUPPLY_STATUS'] == 'Charging' is_charging = output['POWER_SUPPLY_STATUS'] == 'Charging'
charge_percent = float(output['POWER_SUPPLY_CAPACITY']) charge_percent = float(output['POWER_SUPPLY_CAPACITY'])
self.data = {"charge_percent": charge_percent, "charging": is_charging} self.data = {"charge_percent": round(charge_percent, 1), "charging": is_charging}
except: except:
self.data = None self.data = None
@ -293,17 +320,59 @@ class Battery(Sensor):
if d == None: if d == None:
return None return None
else: else:
return [d["charge_percent"], d["charging"]] return [round(d["charge_percent"],1), d["charging"]]
def unpack(self, packed): def unpack(self, packed):
try: try:
if packed == None: if packed == None:
return None return None
else: else:
return {"charge_percent": packed[0], "charging": packed[1]} return {"charge_percent": round(packed[0], 1), "charging": packed[1]}
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
d = self.data
p = d["charge_percent"]
if d["charging"]:
charge_string = "charging"
else:
charge_string = "discharging"
rendered = {
"icon": "battery-outline",
"name": "Battery",
"values": {"percent": p, "_meta": charge_string},
}
if d["charging"]:
if p >= 10: rendered["icon"] = "battery-charging-10"
if p >= 20: rendered["icon"] = "battery-charging-20"
if p >= 30: rendered["icon"] = "battery-charging-30"
if p >= 40: rendered["icon"] = "battery-charging-40"
if p >= 50: rendered["icon"] = "battery-charging-50"
if p >= 60: rendered["icon"] = "battery-charging-60"
if p >= 70: rendered["icon"] = "battery-charging-70"
if p >= 80: rendered["icon"] = "battery-charging-80"
if p >= 90: rendered["icon"] = "battery-charging-90"
if p >= 100: rendered["icon"]= "battery-charging-100"
else:
if p >= 10: rendered["icon"] = "battery-10"
if p >= 20: rendered["icon"] = "battery-20"
if p >= 30: rendered["icon"] = "battery-30"
if p >= 40: rendered["icon"] = "battery-40"
if p >= 50: rendered["icon"] = "battery-50"
if p >= 60: rendered["icon"] = "battery-60"
if p >= 70: rendered["icon"] = "battery-70"
if p >= 80: rendered["icon"] = "battery-80"
if p >= 90: rendered["icon"] = "battery-90"
if p >= 100: rendered["icon"]= "battery-100"
return rendered
class Pressure(Sensor): class Pressure(Sensor):
SID = Sensor.SID_PRESSURE SID = Sensor.SID_PRESSURE
STALE_TIME = 5 STALE_TIME = 5
@ -349,6 +418,17 @@ class Pressure(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "weather-cloudy",
"name": "Ambient Pressure",
"values": { "mbar": self.data["mbar"] },
}
return rendered
class Location(Sensor): class Location(Sensor):
SID = Sensor.SID_LOCATION SID = Sensor.SID_LOCATION
@ -400,12 +480,19 @@ class Location(Sensor):
self.gps.configure(on_location=self.android_location_callback) self.gps.configure(on_location=self.android_location_callback)
self.gps.start(minTime=self._stale_time, minDistance=self._min_distance) self.gps.start(minTime=self._stale_time, minDistance=self._min_distance)
self.update_data() self.update_data()
def teardown_sensor(self): def teardown_sensor(self):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.gps.stop() self.gps.stop()
self.data = None
self.latitude = None
self.longtitude = None
self.altitude = None
self.speed = None
self.bearing = None
self.accuracy = None
self.data = None
def android_location_callback(self, **kwargs): def android_location_callback(self, **kwargs):
self._raw = kwargs self._raw = kwargs
@ -413,7 +500,23 @@ class Location(Sensor):
def update_data(self): def update_data(self):
try: try:
if RNS.vendor.platformutils.is_android(): if self.synthesized:
if self.latitude != None and self.longtitude != None:
if self.altitude == None: self.altitude = 0.0
if self.accuracy == None: self.accuracy = 0.01
if self.speed == None: self.speed = 0.0
if self.bearing == None: self.bearing = 0.0
self.data = {
"latitude": round(self.latitude, 6),
"longtitude": round(self.longtitude, 6),
"altitude": round(self.altitude, 2),
"speed": round(self.speed, 2),
"bearing": round(self.bearing, 2),
"accuracy": round(self.accuracy, 2),
"last_update": int(time.time()),
}
elif RNS.vendor.platformutils.is_android():
if "lat" in self._raw: if "lat" in self._raw:
self.latitude = self._raw["lat"] self.latitude = self._raw["lat"]
if "lon" in self._raw: if "lon" in self._raw:
@ -481,6 +584,25 @@ class Location(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "map-marker",
"name": "Location",
"values": {
"latitude": self.data["latitude"],
"longtitude": self.data["longtitude"],
"altitude": self.data["altitude"],
"speed": self.data["speed"],
"bearing": self.data["bearing"],
"accuracy": self.data["accuracy"],
"updated": self.data["last_update"],
},
}
return rendered
class PhysicalLink(Sensor): class PhysicalLink(Sensor):
SID = Sensor.SID_PHYSICAL_LINK SID = Sensor.SID_PHYSICAL_LINK
STALE_TIME = 5 STALE_TIME = 5
@ -520,6 +642,23 @@ class PhysicalLink(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
q = self.data["q"]
rendered = {
"icon": "network-strength-outline",
"name": "Physical Link",
"values": { "rssi": self.data["rssi"], "snr": self.data["snr"], "q": q },
}
if q != None:
if q > 20: rendered["icon"] = "network-strength-1"
if q > 40: rendered["icon"] = "network-strength-2"
if q > 75: rendered["icon"] = "network-strength-3"
if q > 90: rendered["icon"] = "network-strength-4"
return rendered
class Temperature(Sensor): class Temperature(Sensor):
SID = Sensor.SID_TEMPERATURE SID = Sensor.SID_TEMPERATURE
STALE_TIME = 5 STALE_TIME = 5
@ -554,17 +693,28 @@ class Temperature(Sensor):
if d == None: if d == None:
return None return None
else: else:
return d["percent_relative"] return d["c"]
def unpack(self, packed): def unpack(self, packed):
try: try:
if packed == None: if packed == None:
return None return None
else: else:
return {"percent_relative": packed} return {"c": packed}
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "thermometer",
"name": "Temperature",
"values": { "c": self.data["c"] },
}
return rendered
class Humidity(Sensor): class Humidity(Sensor):
SID = Sensor.SID_HUMIDITY SID = Sensor.SID_HUMIDITY
STALE_TIME = 5 STALE_TIME = 5
@ -610,6 +760,17 @@ class Humidity(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "water-percent",
"name": "Relative Humidity",
"values": { "percent": self.data["percent_relative"] },
}
return rendered
class MagneticField(Sensor): class MagneticField(Sensor):
SID = Sensor.SID_MAGNETIC_FIELD SID = Sensor.SID_MAGNETIC_FIELD
STALE_TIME = 1 STALE_TIME = 1
@ -701,6 +862,17 @@ class AmbientLight(Sensor):
except: except:
return None return None
def render(self, relative_to=None):
if self.data == None:
return None
rendered = {
"icon": "white-balance-sunny",
"name": "Ambient Light",
"values": { "lux": self.data["lux"] },
}
return rendered
class Gravity(Sensor): class Gravity(Sensor):
SID = Sensor.SID_GRAVITY SID = Sensor.SID_GRAVITY
STALE_TIME = 1 STALE_TIME = 1