DerSkythe

mhetesp32minikit

Dec 24th, 2024
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
YAML 14.48 KB | Source Code | 0 0
  1. # The Variables for this device are here AND in the secrets file!
  2. substitutions:
  3.   device_name_friendly: 'Kamer'
  4.   device_name: 'kamer' #DNS NAME!
  5. #More changes after here required.
  6.  
  7. esphome:
  8.   name: ${device_name}
  9.   platform: ESP32
  10.   board: mhetesp32minikit
  11.   on_boot: #For fun let the light transition trough random colours when booting
  12.   #  - light.turn_on:
  13.   #      id: rgblicht
  14.   #      brightness: 100%
  15.   #      red: 0%
  16.   #      green: 0%
  17.   #      blue: 100%
  18.   #  - delay: 1s
  19.   #  - light.control:
  20.   #      id: rgblicht
  21.   #      effect: "Random Effect"
  22.   #  - delay: 10s
  23.   #  - light.control:
  24.   #      id: rgblicht
  25.   #      effect: "none"
  26.     - if: #Turn off the screen after booting if microwave and pir sensor don't see motion.
  27.         condition:
  28.           and:
  29.             - binary_sensor.is_off: microwave
  30.             - binary_sensor.is_off: pir
  31.         then:
  32.           - lambda: id(scherm).turn_off();
  33.  
  34. wifi:
  35.   ssid: !secret wifi_ssid_iot
  36.   password: !secret wifi_password_iot
  37.   #fast_connect: true #probably not necessary
  38.   #reboot_timeout: 45min #probably not necessary
  39.   # power_save_mode: none #fixed regular disconnects causing sensor data to be 'unavailable'. No longer necessar
  40.   # Optional manual IP
  41.   manual_ip:
  42.     static_ip: 192.168.0.25 #Necessary to be able to read the logs and update the device over wifi rather than using an USB cable
  43.     gateway: 92.168.0.1 #probably not necessary
  44.     subnet: 255.255.255.0 #probably not necessary
  45.   #  dns1: 195.130.130.1 #probably not necessary
  46.   #  dns2: 195.130.131.1 #probably not necessary
  47.  
  48.  
  49.   # Enable fallback hotspot (captive portal) in case wifi connection fails
  50.   #ap:
  51.   #  ssid: '${device_name_friendly}Fallback'
  52.   #  password: !secret wifi_fallback_password
  53.  
  54. #captive_portal:
  55.  
  56. # Enable logging
  57. #logger:
  58. #  level: DEBUG
  59.   # level: VERY_VERBOSE I can only get the CO2 sensor manual calibration to work in very verbose mode
  60.  
  61. # Enable Home Assistant API
  62. api:
  63.   password: !secret esphome_local
  64.  
  65. ota:
  66.   password: !secret esphome_local
  67.  
  68. esp32_ble_tracker: #required to activate the bluetooth low energy tracker. Which is needed for the Xiaomi Smart Scale integration and for bluetooth_proxy
  69. bluetooth_proxy: #Home Assistant can expand its Bluetooth reach by communicating through the Bluetooth proxy component in ESPHome
  70.  
  71. light:
  72.   - platform: fastled_clockless
  73.     chipset: WS2812
  74.     pin: GPIO23
  75.     num_leds: 1
  76.     rgb_order: GRB
  77.     name: '${device_name_friendly} RGB LED'
  78.     id: rgblicht
  79.     effects:
  80.       - random:
  81.           name: "Random Effect"
  82.           transition_length: 1s
  83.           update_interval: 1s
  84.  
  85.   # Define pins to be used on the ESP32 for UART which is used by the senseair platform to provide the data
  86. uart:
  87.   rx_pin: GPIO16
  88.   tx_pin: GPIO17
  89.   baud_rate: 9600
  90.  
  91. # setup ic bus
  92. i2c:
  93.   sda: 21
  94.   scl: 22
  95.   scan: True
  96.   id: bus_a #Probably not necessary
  97.  
  98. sensor:
  99.  # - platform: wifi_signal
  100.   #   name: '${device_name_friendly} WiFi Signal'
  101.   #   update_interval: 60s
  102.   - platform: bh1750 #setup illuminance sensor
  103.     id: luminosity
  104.     name: '${device_name_friendly} illuminance'
  105.     address: 0x23
  106.     #measurement_duration: 254 #Higher value allows to measure darker scenes and probably also more accurate but reduces Max range. No longer an option as it is now calculated dynamically
  107.     filters:
  108.       - delta : 0.5
  109.     update_interval: 5s
  110.     on_value:
  111.       then:
  112.         - light.turn_on:
  113.             id: rgblicht
  114.             brightness: !lambda |-
  115.               //sets the brightness of the LED based on luminosity sensor. 0LUX sets brightness to 20% (below that my LED flickers) while 200LUX or higher sets brightness to 100%
  116.               static float brightness_intense = 0.0;
  117.               static float brightness_max = 1.0;
  118.               static float brightness_min = 0.0;
  119.               brightness_intense = (x / 250.0) + 0.2;
  120.               brightness_intense = clamp(brightness_intense,brightness_min,brightness_max);
  121.               return brightness_intense;
  122.   - platform: aht10 #setup temperature & humidity sensor.
  123.     temperature:
  124.       id: '${device_name}temp'
  125.       name: "${device_name_friendly} Temperature"
  126.       filters:
  127.         - offset: +0.5
  128.         - delta : 0.25
  129.     humidity:
  130.       id: '${device_name}hum'
  131.       name: "${device_name_friendly} Humidity"
  132.       filters:
  133.         - offset: -4.0
  134.         - delta : 0.5
  135.     update_interval: 5s
  136.   - platform: senseair #Setup the sensair sensor
  137.     id: '${device_name}CO2'
  138.     co2:
  139.       name: '${device_name_friendly} CO2'
  140.       id: '${device_name}co2state'
  141.       on_value:
  142.         then:
  143.           - light.turn_on:
  144.               id: rgblicht
  145.               state: on
  146.               # brightness: 100% #Already defined this based on luminosity sensor
  147. # Objective: 400ppm=Green; 900ppm=Yellow; 1200ppm=Red with transitions in between
  148. # -->Between 400ppm and 900ppm Red should gradually increase from 0 to 1: Formula: (X-400)/(900-400) & clamp function will restrict result to be between 0 and 1.
  149. # -->Between 900ppm and 1200ppm Green should gradually decrease from 1 to 0: Formula: 1-(X-900)/(1200-900) & clamp function will restrict result to be between 0 and 1.
  150.               red: !lambda |-
  151.                 static float red_intense = 0.0;
  152.                 static float red_max = 1.0;
  153.                 static float red_min = 0.0;
  154.                 ESP_LOGD("main", "Input Number is: %f", x);
  155.                 red_intense = ((x-400.0) / 500.0);
  156.                 ESP_LOGD("main", "Red Number is: %f", red_intense);
  157.                 red_intense = clamp(red_intense,red_min,red_max);
  158.                 ESP_LOGD("main", "Red Number clamped is: %f", red_intense);
  159.                 return red_intense;
  160.               green: !lambda |-
  161.                 static float green_intense = 0.0;
  162.                 static float green_max = 1.0;
  163.                 static float green_min = 0.0;
  164.                 ESP_LOGD("main", "Input Number is: %f", x);
  165.                 green_intense = (1 - (x-900.0) / 300.0);
  166.                 ESP_LOGD("main", "Green Number is: %f", green_intense);
  167.                 green_intense = clamp(green_intense,green_min,green_max);
  168.                 ESP_LOGD("main", "Green Number clamped is: %f", green_intense);
  169.                 return green_intense;
  170.               blue: 0.0
  171.       filters:
  172.         - delta : 4.0 #only send the result if the parts per million difference with the last sent result is higher than this
  173.     update_interval: 4s #delta filter above will prevent too many updates
  174.   - platform: homeassistant #Get value of my outdoor temperature sensor from home assistant
  175.     id: outdoor_temperature
  176.     entity_id: sensor.temperature_buiten
  177.     internal: true
  178.      
  179. binary_sensor:
  180.   - platform: gpio #Microwave technology motion sensor
  181.     pin: GPIO36
  182.     name: '${device_name_friendly} Microwave'
  183.     id: microwave
  184.     internal: true #Don't expose this sensor to Home Assistant
  185.     device_class: motion
  186.     on_state: #turns on the OLED display if microwave motion is detected and turns it off 15 seconds after PIR and Microwave sensors stop detecting motion
  187.       then:
  188.         - if:
  189.             condition:
  190.               - binary_sensor.is_on: microwave
  191.             then:
  192.               - lambda: id(scherm).turn_on();
  193.             else: #The microwave sensor is not detecting motion (anymore)
  194.               - wait_until: #This will stop waiting after 15 seconds or as soon as motion is detected.
  195.                   condition:
  196.                     or:
  197.                       - binary_sensor.is_on: microwave
  198.                       - binary_sensor.is_on: pir
  199.                   timeout: 15s
  200.               - if: #If wait_untill finished due to the timeout it means the motion sensors have not detected any motion for 15s and thus the screen can be turned off. As we don't know whether this is the reason wait_untill finished we need to check whether indeed both sensors are off.
  201.                   condition:
  202.                     and:
  203.                       - binary_sensor.is_off: microwave
  204.                       - binary_sensor.is_off: pir
  205.                   then:
  206.                     - lambda: id(scherm).turn_off();
  207.   - platform: gpio #PIR technology motion sensor
  208.     pin: GPIO19
  209.     id: pir
  210.     internal: true #Don't expose this sensor to Home Assistant
  211.     name: '${device_name_friendly} PIR'
  212.     device_class: motion
  213.     on_state: #turns on the OLED display if PIR motion is detected and turns it off 15 seconds after PIR and Microwave sensors stop detecting motion
  214.       then:
  215.         - if:
  216.             condition:
  217.               - binary_sensor.is_on: pir
  218.             then:
  219.               - lambda: id(scherm).turn_on();
  220.             else: #The pir sensor is not detecting motion (anymore)
  221.               - wait_until: #This will stop waiting after 15 seconds or as soon as motion is detected.
  222.                   condition:
  223.                     or:
  224.                       - binary_sensor.is_on: microwave
  225.                       - binary_sensor.is_on: pir
  226.                   timeout: 15s
  227.               - if: #If wait_untill finished due to the timeout it means the motion sensors have not detected any motion for 15s and thus the screen can be turned off. As we don't know whether this is the reason wait_untill finished we need to check whether indeed both sensors are off.
  228.                   condition:
  229.                     and:
  230.                       - binary_sensor.is_off: microwave
  231.                       - binary_sensor.is_off: pir
  232.                   then:
  233.                     - lambda: id(scherm).turn_off();
  234.   - platform: template #Create virtual motion sensor that is only triggered if both Microwave and PIR sensor see motion
  235.     id: motion
  236.     name: '${device_name_friendly} Motion'
  237.     device_class: motion
  238.     lambda: !lambda |-
  239.       if ((id(microwave).state) and (id(pir).state)) {
  240.         return true;
  241.       } else {
  242.         return false;
  243.       }
  244.  
  245. switch:
  246.   - platform: template
  247.     name: "Trigger background calibration"
  248.     turn_on_action:
  249.       - senseair.background_calibration: '${device_name}CO2'
  250.   #- platform: template #result will be printed in the logs
  251.   #  name: "Get background calibration result"
  252.   #  turn_on_action:
  253.   #    - senseair.background_calibration_result: '${device_name}CO2'
  254.   #- platform: template #result will be printed in the logs
  255.   #  name: "Get ABC Period"
  256.   #  turn_on_action:
  257.   #    - senseair.abc_get_period: '${device_name}CO2'
  258.   - platform: template
  259.     name: "Disable ABC"
  260.     turn_on_action:
  261.       - senseair.abc_disable: '${device_name}CO2'
  262.   - platform: template
  263.     name: "Enable ABC"
  264.     turn_on_action:
  265.       - senseair.abc_enable: '${device_name}CO2'
  266.      
  267.  
  268. font: #Define fonts to be used for the display. font file is to be stored in Home Assistant in folder config/esphome
  269.   - file: 'BebasNeue-Regular.ttf'
  270.     id: font0
  271.     size: 14
  272.   - file: 'BebasNeue-Regular.ttf'
  273.     id: font1
  274.     size: 20
  275.   - file: 'BebasNeue-Regular.ttf'
  276.     id: font2
  277.     size: 26
  278.  
  279. image: #Define images to be used for the display. Image file is to be stored in Home Assistant in folder config/esphome
  280.   - file: "nomotion.png"
  281.     id: nomotionimage
  282.     resize: 35x35
  283.   - file: "motion.png"
  284.     id: motionimage
  285.     resize: 35x35
  286.    
  287. graph:
  288.  # Define auto-ranged CO2 graph
  289.   - id: ${device_name}co2graph
  290.     sensor: ${device_name}co2state #sensor to be used
  291.     duration: 1h #show range of 1 hour
  292.     width: 128
  293.     height: 64
  294.     border: false
  295.     x_grid: 10min #show 1 gridline per 10 minutes
  296.     y_grid: 100 #show 1 gridline per 100PPM co2
  297.    
  298.  
  299. display: #Set up the display
  300.   - platform: ssd1306_i2c
  301.     model: "SSD1306 128x64"
  302.     id: scherm
  303.     # reset_pin: D0  #Optionally you can also connect the RESET pin to a pin on the ESP which may improve reliability. My display doesn't have this pin.
  304.     # address: 0x3C #defaults to 0x3C which should be the right address. Otherwise check the logs.
  305.     update_interval: never #The interval to re-draw the screen. Defaults to 5s. Set to never as I control the updates separately futher below.
  306.     pages: #Insteadf of 1 screen that never changes this defines pages that you can transition between
  307.       - id: page1 #Page with values of all my sensors
  308.         lambda: |-
  309.           // Als buitensensor HomeAssistant beschikbaar: Print Temp gemonteerde sensor + buitensensor van HomeAssistant; anders print enkel temp gemonteerde sensor.
  310.           if (id(outdoor_temperature).has_state()) {
  311.             it.printf(0, 0, id(font1), "°C In:%.1f Out:%.1f", id(${device_name}temp).state, id(outdoor_temperature).state);
  312.           } else {
  313.             it.printf(0, 0, id(font1), "%.1f°C", id(${device_name}temp).state);
  314.           }
  315.           // Print Humidity & LUX value (%% prints %)
  316.           it.printf(0, 20, id(font1), "%.0f%% %.0fLUX", id(${device_name}hum).state, id(luminosity).state);
  317.           // Print CO2 value
  318.           it.printf(0, 40, id(font2), "%.0fppmCO2", id(${device_name}co2state).state);
  319.           //print motion state using an image
  320.           if (id(motion).state) {
  321.             it.image(100, 20, id(motionimage));
  322.           } else {
  323.             it.image(100, 20, id(nomotionimage));
  324.           }
  325.           //Print on bottom right P0M1 if microwave triggered, P1M0 if PIR trigered, P1M1 if both triggered and P0M0 if none triggered
  326.           it.printf(it.get_width(), 50, id(font0), TextAlign::TOP_RIGHT, "%s%s", id(pir).state ? "P1" : "P0", id(microwave).state ? "M1" : "M0");
  327.       - id: page2 # Page with CO2 sensor graph. SHows that gridlines are 10 minues and 100PPm each. Also show the CO2 value on top right.
  328.         lambda: |-
  329.           // Draw the graph at position [x,y]
  330.           it.graph(0, 0, id(${device_name}co2graph));
  331.           it.print(0, 48, id(font0), "10min");
  332.           it.print(0, 0, id(font0), "100ppm");
  333.           it.print(60, 0, id(font0), "CO2");
  334.           it.printf(it.get_width(), 0, id(font1), TextAlign::TOP_RIGHT, "%.0f", id(${device_name}co2state).state);
  335.          
  336.  
  337. # cycle through pages on a timer and regularly update the content. In practice this shows page2 for 3 seconds and then page1 for 10 seconds. Not sure why it's not 7 seconds for page1.
  338. interval:
  339.   - interval: 10s
  340.     then:
  341.       - display.page.show: page2
  342.       - component.update: scherm
  343.       - delay: 3s
  344.       - display.page.show: page1
  345.       - component.update: scherm
  346.       - delay: 1s
  347.       - component.update: scherm
  348.       - delay: 1s
  349.       - component.update: scherm
  350.       - delay: 1s
  351.       - component.update: scherm
  352.       - delay: 1s
  353.       - component.update: scherm
  354.       - delay: 1s
  355.       - component.update: scherm
Add Comment
Please, Sign In to add comment