diff --git a/README.md b/README.md
index bbfb9615b4d24f1ee048a1039867d4893dba5ae3..b732f9c54ab07b39f6718f9fe8673bc039240ddf 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,11 @@ Home Grow(n) Monitoring
     * Dallas DS18B20 Temperature Sensor
 * propbox-light: Nous A1T Smart Plug for Light
 * propbox-fan: Nous A1T Smart Plug for Fan
+* growbox: ESP32 Grow Tent Monitor
+    * Yieryi 3178 EC/pH Monitor (RS485 via XY-485 board)
+    * BME280 Temperature and Humidity Sensor (3.3V, I2C)
+    * SCD40 CO2 Sensor (3.3V, I2C)
+    * MLX90614-DCI IR Temperature Sensor (3.3V, I2C)
 
 ## Configuration
 Copy `secrets.yaml.dist` to `secrets.yaml` and adjust to your preferences.
diff --git a/base.yaml b/base.yaml
index 23171ee766b2a72b10922557a98e230b5e825acd..a381935b7cdcf4fc85794c747db2e379414869bc 100644
--- a/base.yaml
+++ b/base.yaml
@@ -40,7 +40,7 @@ captive_portal:
 
 web_server:
   port: 80
-  local: true
+  # local: true # broken: https://github.com/esphome/issues/issues/3720
   # include_internal: true
 
 sensor:
diff --git a/growbox.yaml b/growbox.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bfb2d0c2299852b52d04f39c69551a4179244b50
--- /dev/null
+++ b/growbox.yaml
@@ -0,0 +1,91 @@
+substitutions:
+  devicename: "growbox"
+  comment: "Grow Tent Monitor"
+
+esphome:
+  includes:
+    - include/yieryi_3178.h
+
+packages:
+  device_base: !include base.yaml
+
+esp32:
+  board: esp32dev
+
+time:
+  - platform: sntp
+    id: sntp_time
+    timezone: ${timezone}
+    update_interval: 1h
+
+prometheus:
+  include_internal: true
+  relabel:
+    rssi:
+      id: rssi
+      name: RSSI
+    device_uptime:
+      id: uptime
+      name: Uptime
+    # temperature:
+    #   id: temperature
+    #   name: Temperature
+    # humidity:
+    #   id: humidity
+    #   name: Humidity
+    # pressure:
+    #   id: pressure
+    #   name: Pressure
+
+i2c:
+  sda: 21
+  scl: 22
+
+uart:
+  id: uart_rs485
+  tx_pin: 19 # TXD
+  rx_pin: 18 # RXD
+  baud_rate: 9600
+
+sensor:
+#   - platform: bme280
+#     address: 0x76
+#     update_interval: 5s
+#     temperature:
+#       id: temperature
+#       name: "Air: Temperature"
+#       accuracy_decimals: 2
+#     humidity:
+#       id: humidity
+#       name: "Air: Humidity"
+#       accuracy_decimals: 2
+#     pressure:
+#       id: pressure
+#       name: "Air: Pressure"
+#       accuracy_decimals: 2
+  - platform: custom
+    lambda: |-
+      auto yieryi_3178 = new Yieryi3178(id(uart_rs485), 5000);
+      App.register_component(yieryi_3178);
+      return {yieryi_3178->ec, yieryi_3178->ph, yieryi_3178->rh, yieryi_3178->temp, yieryi_3178->bat};
+    sensors:
+    - id: water_ec
+      name: "Water: EC"
+      unit_of_measurement: "mS"
+      accuracy_decimals: 3
+    - id: water_ph
+      name: "Water: pH"
+      unit_of_measurement: "pH"
+      accuracy_decimals: 2
+    - id: water_rh
+      name: "Water: RH"
+      unit_of_measurement: "%"
+      accuracy_decimals: 0
+    - id: water_temp
+      name: "Water: Temperature"
+      unit_of_measurement: "°C"
+      accuracy_decimals: 1
+    - id: water_bat
+      name: "Water: Battery"
+      unit_of_measurement: "%"
+      accuracy_decimals: 1
diff --git a/include/nous_a1t.yaml b/include/nous_a1t.yaml
index 342f586ff4dfd4d1b362a26da578252ae49e50c2..ec9ad7796ab85f4995a58a0fc9be85ce317a2f81 100644
--- a/include/nous_a1t.yaml
+++ b/include/nous_a1t.yaml
@@ -4,7 +4,7 @@ esp8266:
 time:
   - platform: sntp
     id: sntp_time
-    timezone: "Europe/Berlin"
+    timezone: ${timezone}
     update_interval: 1h
 
 light:
diff --git a/include/yieryi_3178.h b/include/yieryi_3178.h
new file mode 100644
index 0000000000000000000000000000000000000000..52e3a0981eaaa56f36db6ac94d4160f3a8026e19
--- /dev/null
+++ b/include/yieryi_3178.h
@@ -0,0 +1,77 @@
+#include "esphome.h"
+#include "esphome/core/helpers.h"
+
+class Yieryi3178 : public UARTDevice, public PollingComponent {
+
+  public:
+
+    Sensor *ec   = new Sensor();
+    Sensor *ph   = new Sensor();
+    Sensor *rh   = new Sensor();
+    Sensor *temp = new Sensor();
+    Sensor *bat  = new Sensor();
+
+    Yieryi3178(UARTComponent *parent, uint32_t update_interval) : UARTDevice(parent), PollingComponent(update_interval) {}
+
+    std::vector<uint8_t> bytes;
+
+    typedef union {
+      unsigned char Byte[2];
+      uint16_t UInt16;
+    } TwoByte;
+
+    void update() override {
+
+      byte request[8] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09 };
+
+      write_array(request, sizeof(request));
+      flush();
+      delay(10);
+      
+      while(available() > 0) {
+
+        bytes.push_back(read());      
+
+        if(bytes.size() < 16)
+          continue;  
+
+        if(bytes.size() == 16) {
+
+          ESP_LOGV("yieryi3178", "Bytes received: %s", format_hex_pretty(bytes).c_str());
+
+          TwoByte data_ec;
+          data_ec.Byte[0] = bytes[5];
+          data_ec.Byte[1] = bytes[4];  
+          ec->publish_state(data_ec.UInt16 * 0.001);
+          ESP_LOGD("yieryi3178", "EC: %.3f", data_ec.UInt16 * 0.001);
+
+          TwoByte data_ph;
+          data_ph.Byte[0] = bytes[7];
+          data_ph.Byte[1] = bytes[6];  
+          ph->publish_state(data_ph.UInt16 * 0.01);
+          ESP_LOGD("yieryi3178", "pH: %.2f", data_ph.UInt16 * 0.01);
+
+          TwoByte data_rh;
+          data_rh.Byte[0] = bytes[9];
+          data_rh.Byte[1] = bytes[8];  
+          rh->publish_state(data_rh.UInt16);
+          ESP_LOGD("yieryi3178", "RH: %i", data_rh.UInt16);
+
+          TwoByte data_temp;
+          data_temp.Byte[0] = bytes[11];
+          data_temp.Byte[1] = bytes[10];  
+          temp->publish_state(data_temp.UInt16 * 0.1);
+          ESP_LOGD("yieryi3178", "Temp: %.1f", data_temp.UInt16 * 0.1);
+
+          TwoByte data_bat;
+          data_bat.Byte[0] = bytes[13];
+          data_bat.Byte[1] = bytes[12];  
+          bat->publish_state(data_bat.UInt16 / 100 / 1.5);
+          ESP_LOGD("yieryi3178", "Bat: %.1f", data_bat.UInt16 / 100 / 1.5);
+
+          bytes.clear();
+
+        }
+      }
+    }
+};
\ No newline at end of file