Looking for a clever sod to sort this out!

Any clever coder fancy helping me?
I’m running curl commands via command line to report info from my Radio Thermostat CT80 to Hassio.

Unfortunately they keep timing out as the thermostat is dead slow!
I’ve created a custom component which altered the command_line.py code and adjusted the timeout to 20 sec. Which worked…

However, I was getting hassio warnings all over the shop as it expects things to report within 10s.

Using this custom component also created some unwanted outcomes. Two Arduino voltage sensors now only report their status to hassio on reboot. Even after disabling the custom component.
I’m not sure if the Raspberry pi is just too clogged with delayed requests.

Someone suggested making a script which gathers the information from the thermostat at its own pace, logs it, then command line could extract the info at its leisure.

Here’s my curl commands.

How can I go about making a script to query the thermostat that can then be read by hassio comman_line?

Any help would be greatly appreciated!

Curl commands and info that works with extended time out:

 - platform: command_line
    name: Thermostat
    command: 'curl "192.168.1.123/tstat/temp" -X GET'
    value_template: '{{ value_json.temp }}'
    unit_of_measurement: '°F'
  - platform: command_line
    name: Thermostat Mode
    command: 'curl "192.168.1.123/tstat/tmode" -X GET'
    value_template: '{{ value_json.tmode }}'
    #value_template: "{%if state.sensor.thermostat_mode == '0' %}Off{% elif state.sensor.thermostat_mode == '1' %}Heat{% elif state.sensor.thermostat_mode == '2' %}Cool{% elif state.sensor.thermostat_mode == '3' %}Auto{% endif %}"
  - platform: command_line
    name: Thermostat general stats
    command: 'curl "192.168.1.123/tstat" -X GET'
  - platform: command_line
    name: Thermostat target
    command: 'curl "192.168.1.123/tstat"'
    value_template: '{{ value_json.t_heat }}'
    unit_of_measurement: '°F'
  - platform: command_line
    name: Temporary target
    command: 'curl "192.168.1.123/tstat/override" -X GET'
    value_template: '{{ value_json.override }}'

When it comes to stuff like this I would personally have a python script that runs outside of HA and communicates back to HA via MQTT.

1 Like

Ah right and then just have that load on boot up!
Sounds good. But zero idea where to start…
I’m a noob

Here is a python script I’ve written to communicate with my Kello alarm clock.
Should hopefully give you an example to get started.
It mainly handles receiving messages from MQTT:

Click here to display code
#!/usr/bin/python
# -*- coding: utf-8 -*-

import time
import paho.mqtt.client as mqtt
import subprocess
import datetime

MQTT_Host = "your_mqtt_ip_address"
MQTT_Port = "1883"
MQTT_User = "your_mqtt_user"
MQTT_Password = "your_mqtt_password"


# Ensures main reader program gets killed if main program stops
def Goodbye():
	print "Closing MQTT Connection for Kello..."
	try:
		client.disconnect() #disconnect
		client.loop_stop() #stop loop
	except:
		pass

import atexit
atexit.register(Goodbye)


#define callbacks
def on_message(client, userdata, message):
	if(str(message.payload.decode("utf-8")) == "build_greeting" ):
		print("%s " % datetime.datetime.now().strftime("%d/%m/%y %H:%M") + str(message.payload.decode("utf-8")) )
		cmd = 'echo ichmonix | sudo -S rm /var/www/html/audio/Kello_Greeting.mp3'
		ps = subprocess.Popen(cmd, shell=True)
		time.sleep(1)
		cmd = 'echo ichmonix | sudo -S cp `ls -rt /home/cctv/docker_ha/tts/*.mp3 | tail -1` /var/www/html/audio/Kello_Greeting.mp3'
		ps = subprocess.Popen(cmd, shell=True)
		time.sleep(5)
		cmd = 'echo ichmonix | sudo -S rm `ls -rt /home/cctv/docker_ha/tts/*.mp3`'
		ps = subprocess.Popen(cmd, shell=True)
		cmd = 'printf "\n0d41\r" | nc 192.168.0.17 4444 2>/dev/null'
		ps = subprocess.Popen(cmd, shell=True)
	if(str(message.payload.decode("utf-8")) == "play_greeting" ):
		cmd = 'printf "\n0p41uri:http\:\/\/mydomain\/audio\/Kello_Greeting.mp3?time=' + str(time.time()) + '\r" | nc 192.168.0.17 4444'
		ps = subprocess.Popen(cmd, shell=True)

def on_message_volume(client, userdata, message):
	if(len(str(message.payload.decode("utf-8")))==1):
		Vol = "0" + hex(int(str(message.payload.decode("utf-8"))))[2:]
	else:
		Vol = hex(int(str(message.payload.decode("utf-8"))))[2:]
	cmd = 'printf "\n0p40' + Vol + '\r"  | nc 192.168.0.17 4444 2>/dev/null'
	ps = subprocess.Popen(cmd, shell=True)

def on_message_MuteAlarms(client, userdata, message):
	if (str(message.payload.decode("utf-8")) == "ON" ):
		cmd = 'printf "\n0p231\r" | nc 192.168.0.17 4444 2>/dev/null'
	else:
		cmd = 'printf "\n0d231\r" | nc 192.168.0.17 4444 2>/dev/null'
	ps = subprocess.Popen(cmd, shell=True)

def on_message_PlayStatus(client, userdata, message):
	if (str(message.payload.decode("utf-8")) == "OFF" ):
		cmd = 'printf "\n0d41\r" | nc 192.168.0.17 4444 2>/dev/null'
		ps = subprocess.Popen(cmd, shell=True)



def on_message_radio(client, userdata, message):
	time.sleep(1)
	print("%s " % datetime.datetime.now().strftime("%d/%m/%y %H:%M") + str(message.payload.decode("utf-8")) )
	if (str(message.payload.decode("utf-8")) == "RTL2" ):
		cmd = 'printf "\n0p41uri:http\:\/\/streaming.radio.rtl2.fr\:80\/rtl2-1-44-96\r" | nc 192.168.0.17 4444'
	if (str(message.payload.decode("utf-8")) == "AbsoluteRadio" ):
		cmd = 'printf "\n0p41uri:http\:\/\/icy-e-bab-04-cr.sharp-stream.com\/absoluteradio.mp3\r" | nc 192.168.0.17 4444'
	if (str(message.payload.decode("utf-8")) == "HitWest" ):
		cmd = 'printf "\n0p41uri:http\:\/\/broadcast.infomaniak.ch\/hitwest-high.mp3\r" | nc 192.168.0.17 4444'
	if (str(message.payload.decode("utf-8")) == "Chill" ):
		cmd = 'printf "\n0p41uri:http\:\/\/media-the.musicradio.com\/ChillMP3\r" | nc 192.168.0.17 4444'
	if (str(message.payload.decode("utf-8")) == "WeatherForecast" ):
		cmd = 'printf "\n0p41uri:http\:\/\/mydomain\/audio\/Kello_Greeting.mp3\r" | nc 192.168.0.17 4444'
	if (str(message.payload.decode("utf-8")) == "ConservatoryWindowsLeftOpen" ):
		cmd = 'printf "\n0p41uri:http\:\/\/mydomain\/audio\/Conservatory_Skylights_Left_Open.mp3\r" | nc 192.168.0.17 4444'
	ps = subprocess.Popen(cmd, shell=True)

client = mqtt.Client("MQTT_Kello_Sub", clean_session=False) # must be unique on MQTT network

client.message_callback_add('Kello/PlayStatus', on_message_PlayStatus)
client.message_callback_add('Kello/Volume', on_message_volume)
client.message_callback_add('Kello/Radio', on_message_radio)
client.message_callback_add('Kello/MuteAlarms', on_message_MuteAlarms)
client.on_message=on_message


client.username_pw_set(str(MQTT_User),str(MQTT_Password))
client.connect(MQTT_Host, port=str(MQTT_Port), keepalive=60)

time.sleep(4)
client.subscribe("Kello/#", qos=1)#subscribe
print("Subscribing to Kello on MQTT")
client.loop_forever() #start loop to process received messages

while(True):
	time.sleep(2)

If you need to simply send messages from your script to MQTT (as that’s what times out, I guess sending commands still works?), then it’s even easier.
Below is an example of a code sent from my Raspberry Pi to my HA server to report motion on a PIR connected to the Pi

				MQTT_Command = ["mosquitto_pub", "-h", MQTT_Host, "-p", "1883", "-u", MQTT_User, "-P", MQTT_Password, "-t", "RPi/PIRConservatory", "-r", "-m", "ON"]
				ps = subprocess.Popen(MQTT_Command)

All you’d have to do is to have a script that runs in a loop and use similar commands as your command_line in HA, and post to MQTT for HA to pick up

2 Likes

Fantastic I will start working the grey matter around it…
Thank you

1 Like

Out of curiosity, what’s wrong with using the built in HA component for radio thermostat?

Just says IDLE and most of the functionality doesnt work.
You can switch the modes from heat to cool etc. The AWAY switch works. But it doesnt give temperature readings from the thermostat and adjusting the temperature manually on the dial does nothing.

I’ve manually written some curl commands attached to generic switches and sensors which give me the ability to see which mode its in, what the temperature is, see if there is a temporary target active. I can also set to the thermostat to a pre-defined heating target.

Errors in HA:

“2019-04-14 14:45:40 ERROR (SyncWorker_9) [homeassistant.components.command_line.sensor] Timeout for command: curl “192.168.1.123/tstat/override” -X GET”

“2019-04-14 14:48:00 WARNING (SyncWorker_4) [homeassistant.components.radiotherm.climate] Thermostat (192.168.1.123) was busy (invalid value returned)”

“Timeout for command: curl “192.168.1.123/tstat/temp” -X GET”

Turning the component off again!

You could change your curl command to write the result to a file and then use the file sensor component to get the value into Home Assistant.

Beyond my knowledge atm. Just got the basic curl requests from the radio thermostat (thermostat maker) website.

If there is a problem w/ the radiotherm component, please file a bug report at include the logs and your model number. It’s just making same web calls you’re trying to do by hand. If there is something wrong with it, we can get it fixed. You can also write a simple python script to test it’s functionality (see here: https://github.com/mhrivnak/radiotherm) which might help figure out what’s going on. (FYI - I have two CT50’s that work fine right now - they’re slow and sometimes timeout but they generally work).