Climamota - YAFC - yet another furnace controller

So with the Covid winter in place I thought I would use the time to up my game in home automation. So I have been stepping outside my comfort zone and creating a few projects that take a little more than ordering a light switch or bulb and connecting to HA.

Background
I have had for 1 year a HA environment comprised of:

  • Raspberry Pi 3B+ running HassOS
  • 256G SSD
  • Ubiquiti APs
  • 50+ Tasmota converted bulbs and Light Switches
  • 20+ Zigbee Xaiomi PIR and other sensors

Goal:
To create my own controller using arduino (esp8266 actually) MCU, with relays, and various sensors to connect to my HVAC system.

Requirements:

  • Spouse friendly - the old thermostat still works.
  • Interfaces with Heat, AC, and Fan
  • New wall mounted thermostat interface Tablet
  • Controller must have own directly connect temperature sensor - fail safe
  • Controller must have CH4, CO, and water sensor (phase II)
  • Interfaces with HA using MQTT
  • Automation to include a scheduler

Phase I Solution

Controller
This is the schematic for the circuit board
Furnamota

Components
2 - 5x7cm prototype boards
1 - Wemos D1 mini
1 - DS18B20 thermistor
1 - 3D printed case
1 - 4 channel relay board
1 - 2amp 5V Usb Power supply
1 - Android tablet - cheap Aliexpress no name

Configuration

D5 - Relay1 – controls the furnace fan.

D6 - Relay2 – controls the heater.

D7 - Relay3 – controls the AC.

D2 – connected to the thermistor – a DS18b20.

Notes

My thermistor is inside the original thermostat. The original thermostat is still connected to the furnace and acts a manual controller and also provides a fail safe from freezing in that is it set to turn on the furnace if the temperature drops below 12 degrees. I used spare wiring already run to the thermostat for the thermistor. The original cable was 5 pairs and only 5 wires were in use.

I have also run 5v up to the thermostat to power a tablet mounted to the wall above. The tablet is used to access the lovelace interface. I custom designed a tablet holder and 3D printed it.

Tasmota Configuration

Backlog Ssid Hall-Automation ; Password mywifipassword ; hostname furnacecontroller ; template {"NAME":"Climota smo ","GPIO":[0,0,0,0,1312,0,0,0,257,258,256,0,0,0],"FLAG":0,"BASE":18} ; module 0 ; WebPassword mypassword ; FriendlyName Furnace Controller ; MqttHost 192.168.1.100 ; MqttClient Furnace Controller ; MqttUser mqttc ; MqttPassword mypassword ; Topic furnacecontroller ; NtpServer 192.168.1.100 ; timezone -8 ; wificonfig 5 ; SetOption65 1 ; Tempres 1

Notes

setoption 65 1 sets device to not reset to defaults using fast power cycle detection. This avoids the device going to defaults accidentally or if there is a power bump.

Tempres 1 `sets

resolution of the temperature sensor to 1 decimals. `

Rules

The directly connected thermistor is used in a tasmota rule that does not let the temperature go above 26. ie. if HA messes up and never turns off the heat. So if the temperature is ever above 26 then something is wrong and I want the furnace controller to go into a safe mode. The following rule will turn off the heat relay.

Rule1
On Tele-DS18B20#temperature > 26 Do power2 off endon

The following rule assures that only the AC or the Heat is on.

Rule2
on power2#state=1 do power3 off endon on power3#state=1 do power2 off endon

HA Configurations

HVAC relays

#Furnace Fan Relay
  - platform: mqtt
    name: "Furnace Fan Relay"
    state_topic: "stat/furnacecontroller/RESULT"
    value_template: "{{ value_json.POWER1 }}"
    command_topic: "cmnd/furnacecontroller/POWER1"
    availability_topic: "tele/furnacecontroller/LWT"
    qos: 1
    payload_on: "ON"
    payload_off: "OFF"
    payload_available: "Online"
    payload_not_available: "Offline"
    retain: false
#Furnace Heat Relay
  - platform: mqtt
    name: "Furnace Heat Relay"
    state_topic: "stat/furnacecontroller/RESULT"
    value_template: "{{ value_json.POWER2 }}"
    command_topic: "cmnd/furnacecontroller/POWER2"
    availability_topic: "tele/furnacecontroller/LWT"
    qos: 1
    payload_on: "ON"
    payload_off: "OFF"
    payload_available: "Online"
    payload_not_available: "Offline"
    retain: false
#Furnace A/C Relay
  - platform: mqtt
    name: "Furnace AC Relay"
    state_topic: "stat/furnacecontroller/RESULT"
    value_template: "{{ value_json.POWER3 }}"
    command_topic: "cmnd/furnacecontroller/POWER3"
    availability_topic: "tele/furnacecontroller/LWT"
    qos: 1
    payload_on: "ON"
    payload_off: "OFF"
    payload_available: "Online"
    payload_not_available: "Offline"
    retain: false

Temperature Sensor

  - platform: mqtt
    name: "House Temperature"
    state_topic: "tele/furnacecontroller/SENSOR"
    value_template: "{{ value_json['DS18B20'].Temperature }}"
    unit_of_measurement: "°C"  
    availability_topic: "tele/furnacecontroller/LWT"
    payload_available: "Online"
    payload_not_available: "Offline"
    device_class: temperature

Thermostat Configurations

I have created two thermostats in HA – one for heat and one for AC. The Heat turns on when HA is started with an initial target temperature of 15. The scheduler will set it to whatever I have set.

# House Heat thermostat
climate:
  - platform: generic_thermostat
    name: House Heating
    min_temp: 10
    max_temp: 25
    target_temp: 15
    initial_hvac_mode: "heat" 
    ac_mode: false
    cold_tolerance: 0.3
    hot_tolerance: 0
    min_cycle_duration:
      seconds: 30
    away_temp: 14
    precision: 0.1
    heater: switch.furnance_heat_relay
    target_sensor: sensor.house_temperature
# House AC thermostat
  - platform: generic_thermostat
    name: House AC
    min_temp: 22
    max_temp: 30
    target_temp: 22
    initial_hvac_mode: "off" 
    ac_mode: true
    cold_tolerance: 0
    hot_tolerance: 0.3
    min_cycle_duration:
      seconds: 30
    away_temp: 14
    precision: 0.1
    heater: switch.furnance_ac_relay
    target_sensor: sensor.house_temperature

Automations

This automation simply calls a script every 10 minutes and the script contains the heating schedule

- id: heat_scheduler
  alias: Heat Scheduler
  description: ''
  trigger:
  - platform: homeassistant
    event: start
  - platform: time_pattern
    minutes: /10
  condition: []
  action:
  - service: python_script.thermostat_schedule
    data: {}
  mode: single

Phyton Script to Schedule Heat

WEEK_SCHEDULE = [
    [datetime.time( 0, 0), datetime.time( 1, 0)],     # from 00:00 to 01:00
    [datetime.time( 6, 0), datetime.time( 21, 0)]     # from 07:00 to 09:00
]
WEEKEND_SCHEDULE = [
    [datetime.time( 7, 0), datetime.time( 11, 0)],
    [datetime.time(16, 0), datetime.time(21, 0)]
]

TEMP_HIGH = 23.0
TEMP_LOW  = 15.5

climate_entity = 'climate.house_heating' # set to your thermostat entity
current_temp = hass.states.get(climate_entity).attributes['temperature']

now = datetime.datetime.now().time()
if datetime.datetime.now().date().weekday() < 5:
    current_schedule = WEEK_SCHEDULE
else:
    current_schedule = WEEKEND_SCHEDULE

in_high_time = False
for high_time in current_schedule:
    start = high_time[0]
    end = high_time[1]
    
    if start <= now <= end:        
        in_high_time = True
        break

new_temp = TEMP_HIGH if in_high_time else TEMP_LOW 
if new_temp != current_temp:
    # set the thermostat target temperature.
    hass.services.call('climate', 'set_temperature', {'entity_id': climate_entity, 'temperature': new_temp})

    # also send a notification so that I know that it changed the temperature.
    hass.services.call('notify' , 'notify', {'title' : 'HA: Changing thermostat', 
        'message': 'Changing temperature to {} (was at {})'.format(new_temp, current_temp)})

Enough for now. Phase II will take more electronics than home automation as calibrating a CO and CH4 sensor will take much more thinking. I have also built a garage controller that is mostly working and it needs some time put into it.

Oh, full disclosure - the Python script is not my creation. Found it on the internet by a blogger named abmantis and modified it to work.