Skip to content

Instantly share code, notes, and snippets.

@derglow
Last active January 6, 2021 15:27
Show Gist options
  • Save derglow/67fa00282f9963d07ca29ece98e12bd9 to your computer and use it in GitHub Desktop.
Save derglow/67fa00282f9963d07ca29ece98e12bd9 to your computer and use it in GitHub Desktop.
#substitutions is a list of variables basically. here you can easily change the high/low limits and setpoints
substitutions:
temperature_setpoint: '25.5'
temperature_alarm_low: '23.3'
temperature_alarm_high: '27.5'
temperature_hysteresis: '0.3'
esphome:
name: reefbrain
platform: ESP32
board: nodemcu-32s
on_boot:
priority: -10
# ...
then:
#on boot we turn the thermostat on ("HEAT" mode in my case) and set the desired setpoint
- climate.control:
id: reef_temp_control
mode: HEAT
target_temperature: ${temperature_setpoint}
#This script begins the monitor that makes sure we receive a new temperature measurement at least every 2 minutes
#If this script isn't called every 2 minutes it will start the high temperature alarm
#Everytime we call the script the timer resets. I call this the temperature "heartbeat"
- script.execute: temperature_heartbeat
wifi:
ssid: "Wifi"
password: "Wifi_Password"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Reefbrain Fallback Hotspot"
password: "MRF8tFN7ooul"
#use_address: 192.168.1.20
#You can delete the manual IP config if you want IP address to be assigned automatically
manual_ip:
static_ip: 192.168.1.41
gateway: 192.168.1.1
subnet: 255.255.255.0
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
#I highly recommend passwords! It will prevent you from sending the wrong firmware to the wrong device.
ota:
password: reefbrain
dallas:
#Temperature sensors
- pin: GPIO32
update_interval: 15s
sensor:
#Temperature Sensor 1
- platform: dallas
address: 0xB1031297794BF628
id: reef_temp_1
name: "Reef Temperature 1"
filters:
#I manually calibrated my temperature sensors and figured out this offset
- offset: 1.14
- filter_out: nan
- sliding_window_moving_average:
window_size: 4
send_every: 4
#the next section triggers alarms and the temperature heartbeat
#every time a valid value is received (anything besides NaN) this section is called
on_value:
then:
- if: #if temperature is in range, go ahead and reset the temperature heartbeat timer
condition:
sensor.in_range:
id: reef_temp_1
above: ${temperature_alarm_low}
below: ${temperature_alarm_high}
then:
- script.execute: temperature_heartbeat
- if: #if temperature is below the low limit then trigger the low alarm
condition:
sensor.in_range:
id: reef_temp_1
below: ${temperature_alarm_low}
then:
- switch.turn_on: alarm_temperature_low
- if: #if temperature is above the high limit then trigger the high alarm
condition:
sensor.in_range:
id: reef_temp_1
above: ${temperature_alarm_high}
then:
- switch.turn_on: alarm_temperature_high
#Temperature Sensor 2
- platform: dallas
address: 0x86031497798E6228
id: reef_temp_2
name: "Reef Temperature 2"
filters:
#I manually calibrated my temperature sensors and figured out this offset
- offset: 2.04
- filter_out: nan
- sliding_window_moving_average:
window_size: 4
send_every: 4
#for the second (redundant) temperature sensor I only monitor for the high temperature alarm
on_value:
then:
- if:
condition:
sensor.in_range:
id: reef_temp_2
above: ${temperature_alarm_high}
then:
- switch.turn_on: alarm_temperature_high
switch:
#Heater SSR
- platform: gpio
id: heater_ssr
pin: GPIO0
#I made this internal because the user shouldn't manually manipulate the heater - just the thermostat controller and alarms
internal: true
name: "Heater SSR"
#Making the alarms switches means the microcontroller can trigger the switch on and do the appropriate behavior while
#the user can easily turn it off via Home Assistant
#High Temperature Alarm
- platform: template
name: "High Temperature Alarm"
id: alarm_temperature_high
#if you don't set optimistic to true then the switch automatically turns itself off
optimistic: true
on_turn_on:
- logger.log: "High Temperature Alarm Turned On!"
#change climate control mode to "OFF"
- climate.control:
id: reef_temp_control
mode: "OFF"
#not sure if this is 100% necessary but just to be safe turn off the SSR
- switch.turn_off: heater_ssr
#this while loop runs for as long as the alarm is left on.
#once the user turns the alarm switch off it will exit the while loop
- while:
condition:
switch.is_on: alarm_temperature_high
then:
- logger.log: "High Temperature Alarm Still On!"
- script.execute: triple_siren_short
- delay: 90s
#once the user turns the alarm off we turn the thermostat controller back on i.e. "HEAT"
#the siren script just gives a nice audible feedback that the alarm has been acknowledged/shut off
on_turn_off:
- logger.log: "High Temperature Alarm Turned Off!"
- script.execute: single_siren_short
- climate.control:
id: reef_temp_control
mode: "HEAT"
#Low Temperature Alarm
#This alarm doesn't stop the thermostat, it just sets off a siren.
#One state you might run into is when the system is starting up you may be significantly below the low alarm
#In that case you still want the thermostat to control, so we don't turn off the thermostat here.
#For now this has to be acknowledged before turning off (rather than automatically turning off when in range)
- platform: template
name: "Low Temperature Alarm"
id: alarm_temperature_low
optimistic: true
on_turn_on:
- logger.log: "Low Temperature Alarm Turned On!"
- while:
condition:
switch.is_on: alarm_temperature_low
then:
- logger.log: "Low Temperature Alarm Still On!"
- script.execute: triple_siren_short
- delay: 90s
on_turn_off:
- logger.log: "Low Temperature Alarm Turned Off!"
- script.execute: single_siren_short
#Siren Output
- platform: gpio
pin: GPIO15
id: siren
name: "Siren"
#I made this internal because there's no real usefulness in the user turning it on/off
#The alarms and scripts manage turning it on/off.
internal: true
climate:
- platform: thermostat
id: reef_temp_control
#Note that here the same temperature sensor that has all of the alarms configured is used to control the thermostat
sensor: reef_temp_1
default_target_temperature_low: ${temperature_setpoint}
hysteresis: ${temperature_hysteresis}
heat_action:
- switch.turn_on: heater_ssr
idle_action:
- switch.turn_off: heater_ssr
script:
#the single siren is useful as an acknowledge noise. just one simple chirp
#the scirpt mode has to be queued or else you can't use it properly in the next script
- id: single_siren_short
mode: queued
then:
- switch.turn_on: siren
- delay: 50ms
- switch.turn_off: siren
- delay: 50ms
#the triple chirp is used as the alarm and always implies something is wrong
- id: triple_siren_short
then:
- script.execute: single_siren_short
- script.execute: single_siren_short
- script.execute: single_siren_short
#this script monitors the frequency that we receive new temperature measurements
#if a temperature sensor fails we don't want the thermostat to be stuck high and cook the aquarium
#so the "heartbeat" idea is is that we want a consistent flow of incoming temperature measurements
#if not we should safely shut down and turn on an alarm.
#this script is basically always running. everytime we execute the script is restarts.
#but if we go 2 minutes without restarting it then it will successfully complete and turn on the high alarm
#so everytime the sensor reads a value it will restart this timer.
- id: temperature_heartbeat
mode: restart
then:
- delay: 2 min
- switch.turn_on: alarm_temperature_high
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment