Integrating Comet Wifi basic functionality

Comet Wifi

The Comet Wifi [^1] is a german built decently cheap Wifi (2,4GHz) smart thermostat. They don’t need a gateway and come with their own app. I got these gifted to me so I had to adapt them to HA, but that is only a solution for power users, as it cost me quite a bit of effort to get them running.

Introduction

The Comet Wifi thermostats are fine as standalone devices, altough the app seems pretty terrible.
I wanted to integrate the thermostats in Home Assistant to collect temperature metrics (they include thermometers) and set up central automations.

Setup

You will still need the app for updating the devices and onboarding them to the correct SSID. A couple of things to look out for:

  • You need to temporarily connect to the SSID of the thermostat - make sure you disable the automatic disconnect for the SSID since you won’t reach the internet. My Pixel 6 kept disconnecting from the SSID during setup which makes it impossible to complete. They now also warn about this behaviour in the app now.
  • You need to complete the setup. After pairing with the comet’s SSID the next step will tell you that the setup is complete. Do not close the app, you actually need to press OK/NEXT two more times.

How it works

Many thanks to [^2] for bringing me on the right track on how to go about doing this. There also was a thread on the HA forums discussing this [^3] with the possibility of the API specs being published, although that hasn’t seen updates since october 2021. In short I’m spoofing the DNS entries for the Eurotronic public broker to my own HA server. On this server I run automations and sensors to interact with the thermostats.

Limitations

So far I can set the target temperature and read out the current temperature. This may seem like not a lot but it’s about the capability the Eurotronic app has as well. The app also lets you create and apply heating profiles - setting different target temperatures at different times - holiday profiles, open window detection and of course firmware updates. My devices are running on:

Base-Software: 5.0
Radio-Software: 2.4.2.4

The app also allows reading of a few other metrics (battery level, wifi strength, connection status) which I haven’t gotten around to implementing yet / I don’t know if they are even accessible over MQTT or only via the fabled API.
The profiles we can recreate in Home Assistant pretty easily with automations, for everything else you will need the app.
Most things in the app are set and forget though, the thermostat will (in theory) do everything else by itself.

How to make it work

MQTT

If you don’t care about MQTT or already know how it works skip this part.
Disclamer - I have no idea what I’m talking about but this is my understanding of MQTT right now and how I made it work.
MQTT is an IoT protocol that works over TCP. It uses a centralized Broker to publish messages to Clients using the Topic as a way to determine the corresponding devices.
Here’s how this usually works:

  • A client starts a TCP connection to the broker
  • the client sends an MQTT connect message for authentication
  • the client sends MQTT subscribe messages specifying the topic they want to be informed about
  • once the broker receives a message for that topic it will forward the topic/message combination to the client
  • a client can send a message to whatever topic and the broker will forward this to all subscribed clients

This doesn’t usually need any firewall rules, since the clients are starting the TCP connection to the broker (in Eurotronic’s case a public one) - the connection just gets left open for as long as possible for the broker to inform the client about messages on topics.

The thermostats send unencrypted MQTT messages to either mqtt.eurotronic.io or mqtt1.eurotronic.io.

What you need

You will need:

  • a HA server with a MQTT broker Add-On (I’m using mosquitto)
  • a DNS server that is set by DHCP (I’m using Unbound on OPNSense)
  • probably a bit of patience

Making it work

DNS

Set up a DNS override in your DNS Server pointing to your HA server for the A-Records

mqtt.eurotronic.io
mqtt1.eurotronic.io

In case the devices are in a different network than your HA instance you also need a firewall rule from the devices to HA server on TCP port: 1883.

MQTT

Broker

Install the Mosquitto broker Add-On for Home Assistant and follow the instructions on the documentation page to get it running.

Credentials

Luckily all thermostats use the same username/password combination for the MQTT connection. Add the following to the “Logins” section of your Mosquitto configuration:

- username: 00002F71
  password: 50D6D8B5DA33799A

This worked for me. If your thermostats have different credentials you will see them denied in the mosquitto logs. The way to get the credentials is to packet capture the mqtt connect message - you can trigger an mqtt connect by removing the battery on a device and then putting it back in.

Topics

The thermostats will subscribe to several topics, topics are always constructed like this:

02/00002F71/[Device-MAC]/[Ending]

There are 4 endings that are interesting to us:

  • /S/XX
    • this is the topic the thermostat will use to verify connection to the broker, not necessary but I believe connectivity will be more stable if this is used
  • /S/AF
    • this is the topic where you can request the current target and actual temperature, send the message #0B
  • /V/A0
    • this is the topic the thermostat publishes it’s current target temperature to
  • /V/A1
    • this is the topic the thermostat publishes it’s current actual temperature to
Wildcards

MQTT topics support wildcards, there are two wildcards you can use, # and +:

  • # can only be used at the end of a topic and is a general wildcard for all subtopics that will follow
    • Example: 02/00002F71/# - this will match everyting every thermostat publishes
  • + can only be used in the middle of a topic and is a wildcard for all
    • Example: 02/00002F71/+/V/A0 - this will match for every thermostat but only on the ending for the current target temperature

Home Assistant

At first I tried to set up automations that “translated” the topics into more manageable ones that would make automation easier. As this was my first project with HA I spent about 15 hours getting familiar with yaml and jinja only to scrap all the automations and redo it but oh well.
My current approach utilizes mqtt sensors for the actual temperature and input numbers for the target temperature. Then I have automations set up with mqtt topics as triggers which will in turn execute scripts that interact with the input number and the other way around allowing for bidirectional configuration since after every change on the device, it will also send out the new target temperature.
I will include the configuration samples for one thermostat here.

Value conversion

It would be too easy to just send and receive the values we want as they are so we will need to do a little conversion for incoming and outgoing values.
I will leave them here for easy access and also include them with the configuration examples below.
The thermostat will send a message like #2C which will correspond to the temperature of 22°C.
To get to that value we need to perform a couple of steps:

  • strip the leading #
  • convert to decimal
  • divide by two

These are the conversion templates I came up with:

  • Incoming
    • {{ int(value[1:],base=16)/20 }}
  • Outgoing:
    • {{ "#" + "%0x" %int(float(temp)*2) }}

Looking at this now I’m pretty sure the integer conversion on the outgoing values isn’t needed but oh well.

Configuration

In the configuration we will need the two components discussed above:

mqtt:
	sensor:
		- name: kitchen-temp
			state_topic: 02/00002F71/[Device-MAC]/V/A1
			unit_of_measurement: °C

input_number:
	temp_kitchen:
		name: temp_kitchen
		initial: 20
		min: 13
		max: 30
		step: 0.5
		unit_of_measurement: °C

Automations

To set up a basic dashboard you will need a minimum of 3 automations:

  • Receiving target temperatures
  • Setting temperatures
  • answering #COMM-TEST
- id: ''
	alias: Receive Target Temperature
	description: ''
	trigger:
	  - platform: mqtt
	    topic: 02/00002F71/+/V/A0
	condition: []
	action:
		service: script.update_target_temparature
		data:
			topic: '{{ trigger.topic }}'
			payload: '{{ trigger.payload}}'
	mode: parallel
	max: 50

- id: ''
	alias: Set Target Temperature
	description: ''
	trigger:
	  - platform: state
	    entity_id:
		    #include all your input numbers here
		    - input_number.temp_kitchen
	condition: []
	action:
		service: script.set_temps
		data:
			temp: '{{ trigger.to_state.state }}'
			target: '{{ trigger.entity_id }}'
	mode: parallel
	max: 50

- id: ''
	alias: 'Answer #COMM-TEST'
	description: ''
	trigger:
	  - platform: mqtt
	    topic: 02/00002F71/+/S/XX
	condition: []
	action:
		service: script.answer_test
		data:
			topic: '{{ trigger.topic }}'
	#since request and answer are on the same topic set mode to single and add optional delay otherwise this will run in a loop and drain the battery of your thermostat
	- delay:
		minutes: 1
	mode: single

Scripts

You will also need a minimum of three scripts to pair with these automations

update_target_temparature:
	alias: "Update Target Temperature Input Number"
	fields:
		topic:
			name: Topic
		payload:
			name: Payload
	sequence:
		- choose:
			#choose for the different thermostats, depending on the MAC in the topic
			#repeat this conditions block for every thermostat, replace the device MAC and the input number
			- conditions:
				- condition: template
				  value_template: '{{ topic[12:24] == "[Device MAC]" }}'
			  sequence:
			    - service: input_number.set_value
				    target:
					    entity_id: input_number.temp_kitchen
				    data:
					    value: '{{ int(payload[1:],base=16)/2 }}'
	mode: parallel
	max: 50

set_temps:
	alias: Set Temperature
	fields:
		temp:
			name: Temp
		target:
			name: Target
	sequence:
		- choose:
		    #choose for the different thermostats, depending on the MAC in the topic
		    #repeat this conditions block for every thermostat, replace the device MAC and the input number
			- conditions:
				- condition: template
				  value_template: '{{ target == "input_number.temp_kitchen" }}'
			  sequence:
			    - service: mqtt.publish
			      data:
				      topic: 02/00002F71/[device MAC]/S/A0
				      payload: '{{ "#" + "%0x" %int(float(temp)*2) }}'
				      qos: 2
    mode: parallel
    max: 50

answer_test:
	alias: Answer COMM-TEST
	fields:
		topic:
			name: Topic
		payload:
			name: Payload
	sequence:
		- choose:
		    #choose for the different thermostats, depending on the MAC in the topic
		    #repeat this conditions block for every thermostat, replace the device MAC and the input number
			- conditions:
				- condition: template
					value_template: '{{ topic[12:24] == "[Device MAC]" }}'
				  sequence:
					- service:
					  data:
						  topic: 02/00002F71/[device MAC]/S/XX
						  payload: "#COMM-TEST"
						  qos: 2

Conclusion

With these tools you should have everything you need to never touch the Eurotronic app ever again… surely.
Right now I’m still having some connectivity problems with one thermostat, which keeps reverting to the eurotronics server based on either a DNS cache or a hardcoded IP-Address. This can be fixed by either restarting the device by briefly removing power, or disconnecting them from the SSID manually (I do this on my Aruba IAPs). I might automate this too, so if my firewall can see the thermostat connecting to the public server it will trigger a disconnect by the IAPs but that’s a task for another time.

[^1] Comet Wifi Heizkörperthermostat | EUROTRONIC Technology GmbH
[^2] https://techoverflow.net/2021/12/27/packet-capture-mit-wireshark-des-eurotronic-comet-wifi-heizkoerperthermostats/?lang=de
[^3] Wifi radiator valve thermostat - Eurotronic Comet Wifi

1 Like

Great work! I also did some wiresharking when I was playing with this device. I was looking for the DNS request to be able to do something similar but was not able to find it. I did make notes of the command I found. Especially the S/AF is usefull, when you send it to the device it will respond with a series of messages reporting all kind of internal information

V/ set value
S/ reportvalue

A0 setpoint
A1 current temp
A2 temp Offset
A3 options bitfield keylock / sumertime / rotate display
	#200700 rotate off
	#220500 rotate on
	#230400 activate summertime
	#220500 deactivate summertime
	#270000 key lock on 
	#230400 key lock off

A5 => window open settings #1234 
	last byte = duration in min
	first byte senitivity
	X80 => high
	X08 => middel
	X0C =>low
	
A7 - holiday settings
A8 - AE weekday program

S/AF = #02000000 -- connect with app, request current temp
             #FFFFFFFF - request device to send all fields back

Amazing work! Glad you got it to work!

Super interesting to learn there is an MQTT connection you were able to piggyback on! I take it their MQTT broker does not allow subscriptions for the credentials the thermostats use?

Now I need to order one of these devices to test as well :smiley:

The thermostat will send a message like #2C which will correspond to the temperature of 22°C.

Are you saying the current temperature is published in full degrees resolution? Would be great if you could summarize which actionable data points you were able to see. How about the valve state (0-100%) for example? @FrankBakkerNl is your list complete?

The temperature has a resolution of 1/2 degree. If I recall correctly it is encoded by multiplying the value by 2 and translating to hex in ASCII. The same encoding is uses for setting and reporting temperature valies

I got these commands by monitoring the mqtt messages with an mqtt client while using the app and some experimenting.

When I tried this they had an unsecured Mqtt server in the cloud. I could just connect to that server and see all messages (incl.) Those of other users

I shouldn’t have asked :see_no_evil: wtf

The temperature has a resolution of 1/2 degree

Thanks!

I think the best way to get it to work as a climate in HA is by using this

It can be configured to map target and current temperature from other entities which can then be synced via mqqt

Great finds, those are a lot more than I thought there to be. I only really wiresharked for the temperature values.
I don’t think generic thermostat will really work, unless there’s a trick I don’t know of yet.

It uses a sensor and a switch connected to a heater or air conditioning under the hood.

and it requires a toggle device as a heater, where as we would ideally want an input number:

heater string Required
entity_id for heater switch, must be a toggle device. Becomes air conditioning switch when ac_mode is set to true.

Seems to me this would only turn a device on or off, but that’s a job the thermostats are already doing themselves.

From what I’ve seen there’s a whole new integration needed. I’ve looked into writing integrations a little bit but I’m not sure I could do it yet. I will do more research into what kind of effort that would take.

Super interesting to learn there is an MQTT connection you were able to piggyback on! I take it their MQTT broker does not allow subscriptions for the credentials the thermostats use?

Not sure about that one, I’ve seen in the mosquitto logs that the phone app also authenticates with the same username, although the log entry looked a little different. But if you can reverse engineer the way the phone app works, you could also have HA act as the client probably. Everything is in unencrypted MQTT 3.1 so easy to packet capture.