Closed willclev closed 6 months ago
I have this same problem, where my bedroom environment is controlled by a thermostat in the hallway, and the hallway does not reflect the bedroom temperature at all.
I solved this in home assistant (HA), but I'm a bit cautious about sharing the details because there's a lot of complexity in order to get a robust solution and I'd like a better way. That said, if you're a technical type and would like to dive in...
All the temperature sensors I looked are battery powered and conserve battery life by reporting only if there is a 2 degree or more change, or on a long period like 30 minutes. They are also ugly as sin.
At minimum, I needed a 1 degree change resolution, and I needed it to be timely because my infinity HVAC can change the temperature by nearly 10 degrees in a 30 minute time period. My solution was a custom temperature sensor using a raspberry pi zero W. It is plugged in, so I don't care about conserving power, and it reports once per minute. Integration is in python using Adafruit's libraries for the hardware sensors, and I calibrated loosely off another sensor. I made the enclosure out of some nice oak and it sits on my dresser looking for all the world like our decor, instead of like a red eye of sauron. My wife hasn't commented on it at all, though she keep asking about the ugly motion sensors...
It's a custom integration I made for myself, but I'm sure you can figure out how to integrate a temperature sensor in HA. In my configuration.yaml file it looks like this (the important part being that the entity will end up being named sensor.bedroom_rpi_temperature):
sensor:
- platform: rpi_sensor
name: "Bedroom RPi"
host: "rpi-sensor-bedroom.local"
scan_interval: 60
In HA, I use a custom thermostat integration called "smart thermostat". I don't use the fancy features of it, but it just gives me a generic thermostat that has both heating and cooling. I link the sensor to my RPi temperature sensor, and I created two input_boolean helpers representing "heating_requested" and "cooling_requested" which the thermostat triggers.
- platform: smart_thermostat
name: Bedroom
heater: input_boolean.bedroom_env_heat
cooler: input_boolean.bedroom_env_cool
target_sensor: sensor.bedroom_rpi_temperature
min_temp: 60
max_temp: 80
precision: 0.1
I run the infinitude proxy server in a container with a 512MB limit. For reasons I will sort-of explain later, I set the state on the infinitude integration once per minute. However, infinitude has a memory leak that will crash the host server eventually. This limit forces the server to reboot on a roughly 17-hour cycle. I was previously running this container on the same raspberry pi running HA without this limit, which obviously had disastrous results. The relevant portion of my docker-compose.yaml file is:
version: "3.9"
services:
inf2:
container_name: "inf2"
image: "nebulous/infinitude:latest"
ports:
- "3002:3000"
volumes:
- /usr/local/containers/inf2:/infinitude/state
restart: always
deploy:
resources:
limits:
memory: 512M
The relevant portion of the configuration.yaml for the infinitude integration is:
- platform: infinitude-2
host: homesvcs.local
port: 3002
zone_names:
- Upstairs Hall
I treat the infinitude HVAC system as a big heater or chiller. I built an automation in HA that checks the heating_requested and cooling_requested helpers once per minute, and sets the thermostat state accordingly. I needed to check it this frequently because all of this home automation stuff is ridiculously unreliable, and missing a signal to turn off the heat at the right moment meant waking up at 4am with it being 95 degrees in the bedroom. My wife was not amused when this happened.
I built a big state table covering all the possible infinitude conditions encapsulated in a state vector (heat requested, cooling requested, current mode, running). I actually created HA scripts for every state in this table, with the action to perform to move to the next state based on the requests. I thought I was clever because I execute these scripts using the jinja template language (which I absolutely despise) to build the script name from the given state vector. From my automations.yaml file:
- id: '1636933592878'
alias: Bedroom Temperature
description: ''
trigger:
- platform: time_pattern
minutes: /1
condition: []
action:
- service: script.99bedroomaction_{{ states ('climate.upstairs_hall')[-1] + state_attr('climate.upstairs_hall',
'hvac_action')[-1] + states ('input_boolean.bedroom_env_heat')[-1] + states
('input_boolean.bedroom_env_cool')[-1] }}
- service: input_text.set_value
target:
entity_id: input_text.last_bedroom_state
data:
value: '{{ states (''climate.upstairs_hall'')[-1] + state_attr(''climate.upstairs_hall'',
''hvac_action'')[-1] + states (''input_boolean.bedroom_env_heat'')[-1] + states
(''input_boolean.bedroom_env_cool'')[-1] }}'
mode: single
The state vector I built this way is essentially the last character of each of the states (HVAC mode [heat/cool/off], HVAC status [running/idle], heat requested [on/off], cool requested [on/off]). This substitution creates a script name that is called by the automation action, something like 99bedroomaction_lenf or 99bedroomaction_tgff.
The individual scripts, from my scripts.yaml file:
99bedroomaction_tgnf:
alias: BedroomAction_tgnf
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
+ 2}}'
mode: single
99bedroomaction_teff:
alias: BedroomAction_teff
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
- 2}}'
mode: single
99bedroomaction_lgfn:
alias: BedroomAction_lgfn
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
- 2}}'
mode: single
99bedroomaction_leff:
alias: BedroomAction_leff
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
+ 2}}'
mode: single
99bedroomaction_ffff:
alias: BedroomAction_ffff
sequence:
- delay:
hours: 0
minutes: 0
seconds: 1
milliseconds: 0
mode: single
99bedroomaction_tgff:
alias: BedroomAction_tgff
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
- 2}}'
mode: single
99bedroomaction_tgfn:
alias: BedroomAction_tgfn
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
- 2}}'
mode: single
99bedroomaction_tenf:
alias: BedroomAction_tenf
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
+ 2}}'
mode: single
99bedroomaction_lgnf:
alias: BedroomAction_lgnf
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
+ 2}}'
mode: single
99bedroomaction_lgff:
alias: BedroomAction_lgff
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
+ 2}}'
mode: single
99bedroomaction_lefn:
alias: BedroomAction_lefn
sequence:
- service: climate.set_temperature
target:
entity_id: climate.upstairs_hall
data:
temperature: '{{state_attr (''climate.upstairs_hall'', ''current_temperature'')
- 2}}'
mode: single
99bedroomaction_ffnf:
alias: BedroomAction_ffnf
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: heat
target:
entity_id: climate.upstairs_hall
mode: single
99bedroomaction_fffn:
alias: BedroomAction_fffn
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: cool
target:
entity_id: climate.upstairs_hall
mode: single
99bedroomaction_tefn:
alias: BedroomAction_tefn
sequence:
- service: climate.set_temperature
data:
temperature: 55
target:
entity_id: climate.upstairs_hall
- delay:
hours: 0
minutes: 0
seconds: 3
milliseconds: 0
- service: climate.set_hvac_mode
target:
entity_id: climate.upstairs_hall
data:
hvac_mode: cool
mode: single
99bedroomaction_lenf:
alias: BedroomAction_lenf
sequence:
- service: climate.set_temperature
data:
temperature: 85
target:
entity_id: climate.upstairs_hall
- delay:
hours: 0
minutes: 0
seconds: 3
milliseconds: 0
- service: climate.set_hvac_mode
target:
entity_id: climate.upstairs_hall
data:
hvac_mode: heat
mode: single
The result of all this has been pretty reliable, and the bedroom temperature hovers within a 1 degree window of the target. It will switch between heating and cooling automatically if you want to use the heat/cool option in the thermostat, but I find that's not really the behavior we want.
(I hope to transition this to a pyscript module when I can find some time, or even better to fork MizterB's code here and crate a custom integration that does all this.)
This is best addressed in a Home Assistant automation, not via this integration
Hello, I'm looking to set the thermostat temperature (ie. Current Temperature) from a remote Z-wave temperature sensor which I have added to Home Assistant. My thermostat is not in an ideal location to appropriately obtain an accurate temperature for the heat zone, therefore I'd like to use the remote sensor to set the 'current' temperature for the zone. Is there any way to accomplish this?