mirror of
https://github.com/Crocmagnon/plant-badger.git
synced 2024-11-22 09:28:03 +01:00
Display status with details
This commit is contained in:
parent
ced8d3683a
commit
8f736bc647
1 changed files with 130 additions and 58 deletions
|
@ -1,15 +1,21 @@
|
|||
import badger2040w as badger2040
|
||||
from badger2040w import WIDTH
|
||||
from badger2040w import WIDTH, Badger2040W
|
||||
import urequests
|
||||
|
||||
import secrets
|
||||
from secrets import HA_BASE_URL, HA_ACCESS_TOKEN
|
||||
|
||||
|
||||
display = badger2040.Badger2040W()
|
||||
display = Badger2040W()
|
||||
display.led(128)
|
||||
display.set_update_speed(2)
|
||||
BLACK = 0
|
||||
WHITE = 15
|
||||
|
||||
display.connect()
|
||||
|
||||
LINE_START_OFFSET = 3
|
||||
STATUS_VALUE_OFFSET = 25
|
||||
|
||||
|
||||
class HAError(Exception):
|
||||
pass
|
||||
|
@ -19,66 +25,132 @@ class HAFetchStateError(HAError):
|
|||
pass
|
||||
|
||||
|
||||
class HAPlant:
|
||||
def __init__(self, entity_id):
|
||||
self.entity_id = entity_id
|
||||
self.state = None
|
||||
self._last_fetched = None
|
||||
def fetch_state(entity: str) -> dict:
|
||||
headers = {
|
||||
"Authorization": f"Bearer {HA_ACCESS_TOKEN}",
|
||||
"content-type": "application/json",
|
||||
}
|
||||
url = f"{HA_BASE_URL}/states/{entity}"
|
||||
print("Fetching state from", url)
|
||||
res = urequests.get(url, headers=headers)
|
||||
if res.status_code != 200:
|
||||
msg = f"Error fetching state for {entity}: {res.text}"
|
||||
raise HAFetchStateError(msg)
|
||||
data = res.json()
|
||||
res.close()
|
||||
del data["context"]
|
||||
print(data)
|
||||
return data
|
||||
|
||||
def fetch_state(self) -> None:
|
||||
"""Fetch state and store in self.state."""
|
||||
headers = {
|
||||
"Authorization": f"Bearer {HA_ACCESS_TOKEN}",
|
||||
"content-type": "application/json",
|
||||
}
|
||||
url = f"{HA_BASE_URL}/states/{self.entity_id}"
|
||||
print("Fetching state from", url)
|
||||
res = urequests.get(url, headers=headers)
|
||||
if res.status_code != 200:
|
||||
msg = f"Error fetching state for {self.entity_id}: {res.text}"
|
||||
raise HAFetchStateError(msg)
|
||||
data = res.json()
|
||||
self.state = data
|
||||
res.close()
|
||||
|
||||
class HAPlant:
|
||||
def __init__(self):
|
||||
self._last_fetched = None
|
||||
self.plant_state = None
|
||||
# Example state
|
||||
# {
|
||||
# "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",
|
||||
# }
|
||||
|
||||
def get_plant_attribute(self, attribute):
|
||||
return self.plant_state.get("attributes", {}).get(attribute, None)
|
||||
|
||||
def get_detailed_state(self, attribute):
|
||||
return self.details.get(attribute, {}).get("state", None)
|
||||
|
||||
def get_detailed_attribute(self, attribute, attribute_name):
|
||||
return (
|
||||
self.details.get(attribute, {})
|
||||
.get("attributes", {})
|
||||
.get(attribute_name, None)
|
||||
)
|
||||
|
||||
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):
|
||||
print(self.state)
|
||||
# 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()
|
||||
|
||||
|
||||
def draw_page(plant):
|
||||
print("Drawing page...")
|
||||
# Clear the display
|
||||
display.set_pen(15)
|
||||
display.clear()
|
||||
display.set_pen(0)
|
||||
|
||||
# Draw the page header
|
||||
display.set_font("bitmap6")
|
||||
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")
|
||||
display.set_pen(0)
|
||||
display.rectangle(0, 60, WIDTH, 25)
|
||||
display.set_pen(15)
|
||||
display.text(
|
||||
"Found state, check logs",
|
||||
5,
|
||||
65,
|
||||
WIDTH,
|
||||
1,
|
||||
)
|
||||
|
||||
display.update()
|
||||
plant.display_state()
|
||||
|
||||
|
||||
plant = HAPlant("plant.aloe_vera")
|
||||
plant.fetch_state()
|
||||
draw_page(plant)
|
||||
plant = HAPlant()
|
||||
plant.fetch_states()
|
||||
plant.display_state()
|
||||
|
||||
# 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.
|
||||
|
|
Loading…
Reference in a new issue