Display status with details

This commit is contained in:
Gabriel Augendre 2023-03-10 15:43:12 +01:00
parent ced8d3683a
commit 8f736bc647

View file

@ -1,15 +1,21 @@
import badger2040w as badger2040 from badger2040w import WIDTH, Badger2040W
from badger2040w import WIDTH
import urequests import urequests
import secrets
from secrets import HA_BASE_URL, HA_ACCESS_TOKEN from secrets import HA_BASE_URL, HA_ACCESS_TOKEN
display = badger2040.Badger2040W() display = Badger2040W()
display.led(128) display.led(128)
display.set_update_speed(2) display.set_update_speed(2)
BLACK = 0
WHITE = 15
display.connect() display.connect()
LINE_START_OFFSET = 3
STATUS_VALUE_OFFSET = 25
class HAError(Exception): class HAError(Exception):
pass pass
@ -19,66 +25,132 @@ class HAFetchStateError(HAError):
pass pass
class HAPlant: def fetch_state(entity: str) -> dict:
def __init__(self, entity_id):
self.entity_id = entity_id
self.state = None
self._last_fetched = None
def fetch_state(self) -> None:
"""Fetch state and store in self.state."""
headers = { headers = {
"Authorization": f"Bearer {HA_ACCESS_TOKEN}", "Authorization": f"Bearer {HA_ACCESS_TOKEN}",
"content-type": "application/json", "content-type": "application/json",
} }
url = f"{HA_BASE_URL}/states/{self.entity_id}" url = f"{HA_BASE_URL}/states/{entity}"
print("Fetching state from", url) print("Fetching state from", url)
res = urequests.get(url, headers=headers) res = urequests.get(url, headers=headers)
if res.status_code != 200: if res.status_code != 200:
msg = f"Error fetching state for {self.entity_id}: {res.text}" msg = f"Error fetching state for {entity}: {res.text}"
raise HAFetchStateError(msg) raise HAFetchStateError(msg)
data = res.json() data = res.json()
self.state = data
res.close() res.close()
del data["context"]
def display_state(self): print(data)
print(self.state) return data
def draw_page(plant): class HAPlant:
print("Drawing page...") def __init__(self):
# Clear the display self._last_fetched = None
display.set_pen(15) self.plant_state = None
display.clear() # Example state
display.set_pen(0) # {
# "entity_id": "plant.aloe_vera",
# "state": "problem",
# "attributes": {
# "species": "Aloe vera",
# "moisture_status": "ok",
# "temperature_status": "ok",
# "conductivity_status": "Low",
# "illuminance_status": "ok",
# "humidity_status": null,
# "dli_status": "Low",
# "species_original": "aloe vera",
# "device_class": "plant",
# "entity_picture": "https://opb-img.plantbook.io/aloe%20vera.jpg",
# "friendly_name": "Aloe vera"
# },
# "last_changed": "2023-03-10T12:51:29.103630+00:00",
# "last_updated": "2023-03-10T12:52:47.188669+00:00",
# }
self.details = {}
# Example illuminance state
# {
# "entity_id": "sensor.aloe_vera_illuminance",
# "state": "245",
# "attributes": {
# "state_class": "measurement",
# "unit_of_measurement": "lx",
# "device_class": "illuminance",
# "friendly_name": "Aloe vera Illuminance"
# },
# "last_changed": "2023-03-10T13:58:08.838316+00:00",
# "last_updated": "2023-03-10T13:58:08.838316+00:00",
# }
# Draw the page header def get_plant_attribute(self, attribute):
display.set_font("bitmap6") return self.plant_state.get("attributes", {}).get(attribute, None)
display.set_pen(0)
display.rectangle(0, 0, WIDTH, 20)
display.set_pen(15)
display.text("Weather", 3, 4)
display.set_pen(0)
display.set_font("bitmap8") def get_detailed_state(self, attribute):
display.set_pen(0) return self.details.get(attribute, {}).get("state", None)
display.rectangle(0, 60, WIDTH, 25)
display.set_pen(15) def get_detailed_attribute(self, attribute, attribute_name):
display.text( return (
"Found state, check logs", self.details.get(attribute, {})
5, .get("attributes", {})
65, .get(attribute_name, None)
WIDTH,
1,
) )
def get_plant_status(self, attribute):
status = self.get_plant_attribute(f"{attribute}_status")
if status is None:
return "N/A"
status = status.upper()
if status == "OK":
return "OK"
detailed_state = self.get_detailed_state(
attribute
) + self.get_detailed_attribute(attribute, "unit_of_measurement")
if status == "LOW":
return f"Bas ({detailed_state})"
if status == "HIGH":
return f"Haut ({detailed_state})"
return status
def fetch_states(self) -> None:
self.plant_state = fetch_state(secrets.HA_PLANT_ID)
self.details["moisture"] = fetch_state(secrets.HA_PLANT_MOISTURE_SENSOR)
self.details["illuminance"] = fetch_state(secrets.HA_PLANT_ILLUMINANCE_SENSOR)
self.details["temperature"] = fetch_state(secrets.HA_PLANT_TEMPERATURE_SENSOR)
self.details["conductivity"] = fetch_state(secrets.HA_PLANT_CONDUCTIVITY_SENSOR)
print(self.details)
def display_state(self):
# Clear the display
display.set_pen(WHITE)
display.clear()
# Draw the page header
display.set_pen(BLACK)
display.rectangle(0, 0, WIDTH, 20)
# Write text in header
display.set_font("bitmap6")
display.set_pen(WHITE)
display.text(self.get_plant_attribute("friendly_name"), 3, 4)
display.set_pen(BLACK)
display.text("H", LINE_START_OFFSET, 30)
display.text("T", LINE_START_OFFSET, 55)
display.text("C", LINE_START_OFFSET, 80)
display.text("L", LINE_START_OFFSET, 105)
display.set_font("bitmap8")
display.text(self.get_plant_status("moisture"), STATUS_VALUE_OFFSET, 30)
display.text(self.get_plant_status("temperature"), STATUS_VALUE_OFFSET, 55)
display.text(self.get_plant_status("conductivity"), STATUS_VALUE_OFFSET, 80)
display.text(self.get_plant_status("illuminance"), STATUS_VALUE_OFFSET, 105)
display.update() display.update()
plant.display_state()
plant = HAPlant("plant.aloe_vera") plant = HAPlant()
plant.fetch_state() plant.fetch_states()
draw_page(plant) plant.display_state()
# Call halt in a loop, on battery this switches off power. # Call halt in a loop, on battery this switches off power.
# On USB, the app will exit when A+C is pressed because the launcher picks that up. # On USB, the app will exit when A+C is pressed because the launcher picks that up.