How to send multiple writeAttributes in one message?

Hey folks. I'm hammering out a driver for the Hive thermostat and receiver, and it's largely complete. However, I'm having real trouble with the boost command. Sniffed from the OEM system it looks like this:

This sets boost mode at 22degC for 1 hour. But when I attempt to replicate it with this code:

void emergencyHeat() {
	// Boost mode.

	//logging("${device} : Heating Boost : This feature has not been implemented yet. Please boost from the thermostat.", "warn")
	//return

	int boostTime = 60
	int boostTemp = 2200
	logging("${device} : Heating Boost : Attempting to boost to ${boostTemp} for ${boostTime} minutes", "debug")

	ArrayList<String> cmds = []
	cmds += zigbee.writeAttribute(0x0201, 0x001C, 0x30, 0x05, [destEndpoint: 0x05])		// SystemMode
	cmds += zigbee.writeAttribute(0x0201, 0x0023, 0x30, 0x01, [destEndpoint: 0x05])		// TemperatureSetpointHold
	cmds += zigbee.writeAttribute(0x0201, 0x0024, 0x21, boostTime, [destEndpoint: 0x05])	// TemperatureSetpointHoldDuration
	cmds += zigbee.writeAttribute(0x0201, 0x0012, 0x29, boostTemp, [destEndpoint: 0x05]) 	// OccupiedHeatingSetpoint
	sendZigbeeCommands(cmds)

	//runIn(3,getThermostatMode)

}

It sets boost mode and the target temperature correctly, but utterly fails with the countdown timer and the system tries to boost for over five hours. Eventually I stumbled upon this potential explanation from the SLR2's Zigbee2MQTT page:

Note: For device timing reasons, the payload needs to be sent as one single command. Sending individual commands or settings attributes manually using the Frontend will not work.

That sounds familiar. So, in my code am I essentially sending four sequential commands? And if so, how do I construct this into one command as the device seems to require?

Cheers all!

Not sure if it will help but if you look at the output of zigbee.writeAttribute() a 2 second delay is inserted by default. You could try removing it.

1 Like

Oh, is there? Thanks, I don't know off the top of my head how to zero out the delay, but I do know how to construct the raw commands (which I'll assume doesn't do that). Thanks, I shall give it a try.

You can strip it from the list manually or

4 Likes

Oh my word, I can't belive it was this easy:

void emergencyHeat() {
	// Boost mode.

	int boostTime = 30
	int boostTemp = 2300
	logging("${device} : Heating Boost : Attempting to boost to ${boostTemp} for ${boostTime} minutes", "debug")

	ArrayList<String> cmds = []
	cmds += zigbee.writeAttribute(0x0201, 0x001C, 0x30, 0x05, [destEndpoint: 0x05], 0)			// SystemMode
	cmds += zigbee.writeAttribute(0x0201, 0x0023, 0x30, 0x01, [destEndpoint: 0x05], 0)			// TemperatureSetpointHold
	cmds += zigbee.writeAttribute(0x0201, 0x0024, 0x21, boostTime, [destEndpoint: 0x05], 0)		// TemperatureSetpointHoldDuration
	cmds += zigbee.writeAttribute(0x0201, 0x0012, 0x29, boostTemp, [destEndpoint: 0x05], 0) 	// OccupiedHeatingSetpoint
	sendZigbeeCommands(cmds)

	//runIn(3,getThermostatMode)

}

Perfect 30 minute boost has just started on my test setup. It's happily reporting in with the remaining minutes on boost. Thank you! :smiley:

5 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.