From cf9ae04ce0f362afe7d9b480f544ce18ca1501fb Mon Sep 17 00:00:00 2001
From: Jan Grewe <jan@faked.org>
Date: Mon, 15 Jul 2024 01:24:34 +0200
Subject: [PATCH] tweak graphs

---
 img/screen_growsmart.png      | Bin 0 -> 8231 bytes
 packages/display_cyd2usb.yaml |  64 +++++++---
 packages/mqtt.yaml            |   9 ++
 packages/screen.yaml          | 231 ++++++++++++++++++++++------------
 4 files changed, 207 insertions(+), 97 deletions(-)
 create mode 100644 img/screen_growsmart.png

diff --git a/img/screen_growsmart.png b/img/screen_growsmart.png
new file mode 100644
index 0000000000000000000000000000000000000000..cdc677fc0875f8b781e45f91acbe879cc207bace
GIT binary patch
literal 8231
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
VL2!o9F{@ILh^MQc%Q~loCIF4xtiJ#N

literal 0
HcmV?d00001

diff --git a/packages/display_cyd2usb.yaml b/packages/display_cyd2usb.yaml
index c597843..db2e010 100644
--- a/packages/display_cyd2usb.yaml
+++ b/packages/display_cyd2usb.yaml
@@ -27,14 +27,7 @@ display:
     dimensions:
       height: 320
       width: 240
-    lambda: |-
-      it.fill(id(Color::BLACK));
-      it.line(0, 0, 50, 50);
-      it.filled_circle(60, 160, 30, id(green));
-      it.filled_circle(180, 160, 30, id(red));
-      it.print(60, 160, id(mdi_large), TextAlign::CENTER, "󰛨");
-      it.print(180, 160, id(mdi_large), TextAlign::CENTER, "󰛨");
-      it.print(216, 0, id(mdi_medium), id(wifi_iconstring).c_str());
+    lambda: id(update_display).execute();
 
 # Set up the xpt2046 touch platform
 touchscreen:
@@ -90,29 +83,60 @@ light:
     red: output_red
     green: output_green
     blue: output_blue
-    gamma_correct: 1.0
     restore_mode: ALWAYS_ON
     effects:
       - pulse:
           name: "Default"
           transition_length: 3s
           update_interval: 3s
-          min_brightness: 33%
+          min_brightness: 50%
           max_brightness: 100%
+      - strobe:
+          name: "Alert"
+          colors:
+            - state: true
+              brightness: 100%
+              red: 100%
+              green: 0%
+              blue: 0%
+              duration: 250ms
+            - state: false
+              duration: 250ms
     on_turn_on:
       - light.turn_on:
           id: led
           effect: "Default"
+          brightness: 100%
+          red: 0%
+          green: 100%
+          blue: 0%
 
 interval:
-  - interval: 5s
+  - interval: 10s
     then:
-      - if:
-          condition:
-            - lambda: "return !id(recent_touch);"
-          then:
-            - light.turn_on:
-                id: backlight
-                brightness: 25%
-          else:
-            - lambda: "id(recent_touch) = false;"
+      - lambda: |-
+          // dim the display to 50% after 10s, and to 25% after 20s
+          if (id(recent_touch))
+          {
+            id(recent_touch) = false;
+            id(screen_timeout_short) = true;
+          }
+          else if (id(screen_timeout_short)) 
+          {
+            id(screen_timeout_short) = false;
+            id(screen_timeout_long) = true;
+            auto call = id(backlight).turn_on();
+            call.set_brightness(0.5);
+            call.perform();
+          }
+          else if (id(screen_timeout_long))
+          {
+            id(screen_timeout_long) = false;
+            auto call = id(backlight).turn_on();
+            call.set_brightness(0.25);
+            call.perform();
+          }
+
+button:
+  - platform: factory_reset
+    name: Factory Reset
diff --git a/packages/mqtt.yaml b/packages/mqtt.yaml
index 50e4678..d3665a3 100644
--- a/packages/mqtt.yaml
+++ b/packages/mqtt.yaml
@@ -5,4 +5,13 @@ mqtt:
   client_id: $devicename
   discovery: false
   topic_prefix: growsmart/$devicename
+  log_topic:
+    topic: growsmart/$devicename/log
+    level: INFO
+  birth_message:
+    topic: growsmart/$devicename/status
+    payload: online
+  will_message:
+    topic: growsmart/$devicename/status
+    payload: offline
   reboot_timeout: 0s
diff --git a/packages/screen.yaml b/packages/screen.yaml
index 4afe3bf..5387051 100644
--- a/packages/screen.yaml
+++ b/packages/screen.yaml
@@ -1,52 +1,45 @@
+substitutions:
+  graph_duration: 15min
+  graph_grid_x: 1min
 
-# Set up some global variables for some values that we want to persist
 globals:
-  - id: wifi_iconstring
-    type: std::string
-    restore_value: no
-    initial_value: '"󰤮"'
   - id: recent_touch
     type: bool
-    restore_value: no
-    initial_value: "true"
+    initial_value: 'true'
+  - id: screen_timeout_short
+    type: bool
+  - id: screen_timeout_long
+    type: bool
+  - id: temperature
+    type: float
+    initial_value: '0.0'
+  - id: humidity
+    type: float
+    initial_value: '0.0'
+  - id: ec
+    type: float
+    initial_value: '0.0'
+  - id: ph
+    type: float
+    initial_value: '0.0'
 
-# ============================================================ 
-# ESPHome Display related setup
-#
-# Create a font to use, add and remove glyphs as needed
-# The Material Design Icon font is going to be used to display wifi
-# state as well as displaying the lightbulb icons
 font:
-  - file: 'packages/fonts/materialdesignicons-webfont.ttf'
-    id: mdi_large
-    size: 48
-    glyphs: [
-        "󰛨", # lightbulb-on
-        "󰹏", # lightbulb-off
-    ]
-  - file: "packages/fonts/materialdesignicons-webfont.ttf"
-    id: mdi_medium
-    size: 24
-    glyphs: [
-        "󰤮", # no-wifi
-        "󰤫", # low-wifi
-        "󰤟", # wifi-1
-        "󰤢", # wifi-2
-        "󰤥", # wifi-3
-        "󰤨", # wifi-4
-    ]
+  - file:
+      type: gfonts
+      family: Roboto
+      weight: 700
+    id: font_default
+    size: 16
+    glyphs: '!"%()+=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ abcdefghijklmnopqrstuvwxyzåäö'
 
-# Create a Home Assistant blue color
-color:
-  - id: green
-    hex: 00FF00
-  - id: red
-    hex: FF0000
+image:
+  - file: "img/screen_growsmart.png"
+    id: growsmart
+    type: RGB24
 
-# Setup two binary sensors for the two areas for touch
 binary_sensor:
   - platform: touchscreen
-    name: Light Green
+    name: "LED Default"
     x_min: 0
     x_max: 120
     y_min: 0
@@ -55,12 +48,10 @@ binary_sensor:
       then:
         - light.turn_on:
             id: led
-            red: 0.0
-            green: 1.0
-            blue: 0.0            
+            effect: Default
 
   - platform: touchscreen
-    name: Light Red
+    name: "LED Alert"
     x_min: 120
     x_max: 240
     y_min: 0
@@ -69,43 +60,129 @@ binary_sensor:
       then:
         - light.turn_on:
             id: led
-            red: 1.0
-            green: 0.0
-            blue: 0.0
+            effect: Alert
 
-
-# Setup a script that can update the UI values independent of the display lambda
-# so that we're not trying to pull the WiFi signal strength every single frame
 script:
-  - id: update_ui_values
+  - id: update_display
     then:
-    - lambda: |-
-        if (isnan(id(wifi_signal_pct).state))
-            id(wifi_iconstring) = "󰤮"; // No-wifi
-        else if (id(wifi_signal_pct).state < 10)
-            id(wifi_iconstring) = "󰤟";  // low-wifi
-        else if (id(wifi_signal_pct).state < 30)
-            id(wifi_iconstring) = "󰤟"; // wifi-1
-        else if (id(wifi_signal_pct).state < 50)
-            id(wifi_iconstring) = "󰤢"; // wifi-2
-        else if (id(wifi_signal_pct).state < 75)
-            id(wifi_iconstring) = "󰤥"; // wifi-3
-        else
-            id(wifi_iconstring) = "󰤨"; // wifi-4
+      - lambda: |-
+          if (id(temperature) == 0.0 || id(humidity) == 0.0 || id(ph) == 0.0 || id(ec) == 0.0)
+          {
+            esp_display->image(0, 0, id(growsmart));
+            return;
+          }
+          esp_display->fill(id(Color::BLACK));
+          esp_display->printf(0,   0, id(font_default), "Temperature: %.2f °C", id(temperature));
+          esp_display->graph(0,   18, id(graph_temperature));
+          esp_display->printf(0,  80, id(font_default), "Humidity: %.2f%%", id(humidity));
+          esp_display->graph(0,   98, id(graph_humidity));
+          esp_display->printf(0, 160, id(font_default), "pH: %.2f", id(ph));
+          esp_display->graph(0,  178, id(graph_ph));
+          esp_display->printf(0, 240, id(font_default), "EC: %.2f mS", id(ec));
+          esp_display->graph(0,  258, id(graph_ec));
 
-# Update the UI state every 10 seconds
-interval:
-  - interval: 1s
-    then:
-      - script.execute: update_ui_values
+color:
+  - id: color_red
+    red: 100%
+    green: 0%
+    blue: 0%
+  - id: color_green
+    red: 0%
+    green: 100%
+    blue: 0%
+  - id: color_blue
+    red: 0%
+    green: 0%
+    blue: 100%
+
+graph:
+  - id: graph_temperature
+    duration: ${graph_duration}
+    x_grid: ${graph_grid_x}
+    y_grid: 1.0
+    width: 240
+    height: 60
+    min_value: 18
+    max_value: 32
+    min_range: 2
+    max_range: 2
+    traces:
+      - sensor: mqtt_temperature
+        continuous: true
+        #line_thickness: 2
+        color: color_green
+  - id: graph_humidity
+    duration: ${graph_duration}
+    x_grid: ${graph_grid_x}
+    y_grid: 1.0
+    width: 240
+    height: 60
+    min_value: 40
+    max_value: 90
+    min_range: 2
+    max_range: 2
+    traces:
+      - sensor: mqtt_humidity
+        continuous: true
+        #line_thickness: 2
+        color: color_green
+  - id: graph_ph
+    duration: ${graph_duration}
+    x_grid: ${graph_grid_x}
+    y_grid: 1.0
+    width: 240
+    height: 60
+    min_value: 4
+    max_value: 8
+    min_range: 2
+    max_range: 2
+    traces:
+      - sensor: mqtt_ph
+        continuous: true
+        #line_thickness: 2
+        color: color_green
+  - id: graph_ec
+    duration: ${graph_duration}
+    x_grid: ${graph_grid_x}
+    y_grid: 1.0
+    width: 240
+    height: 60
+    min_value: 0
+    max_value: 3
+    min_range: 2
+    max_range: 2
+    traces:
+      - sensor: mqtt_ec
+        continuous: true
+        #line_thickness: 2
+        color: color_green
 
-# Wifi sensor that drives the UI signal strength icon
 sensor:
-  - platform: wifi_signal # Reports the WiFi signal strength in %
-    name: "WiFi Signal Percent"
-    filters:
-      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
-    unit_of_measurement: "Signal %"
-    id: wifi_signal_pct
-    update_interval: 60s
-    entity_category: "diagnostic"
+  - platform: mqtt_subscribe
+    id: mqtt_temperature
+    name: "Temperature"
+    topic: growsmart/growbox/sensor/air__temperature/state
+    on_value:
+      then:
+        - lambda: 'id(temperature) = x;'
+  - platform: mqtt_subscribe
+    id: mqtt_humidity
+    name: "Humidity"
+    topic: growsmart/growbox/sensor/air__humidity/state
+    on_value:
+      then:
+        - lambda: 'id(humidity) = x;'
+  - platform: mqtt_subscribe
+    id: mqtt_ec
+    name: "EC"
+    topic: growsmart/growbox/sensor/ec/state
+    on_value:
+      then:
+        - lambda: 'id(ec) = x;'
+  - platform: mqtt_subscribe
+    id: mqtt_ph
+    name: "pH"
+    topic: growsmart/growbox/sensor/ph/state
+    on_value:
+      then:
+        - lambda: 'id(ph) = x;'
-- 
GitLab