Help required as I develop an Edge driver for my Secure SRT323 Thermostat

So, my Secure Thermostats (SRT323 and SRT321), which require custom Groovy drivers and cloud execution will stop working in about 3 weeks, just as the temperature drops here in the UK.
By cut and paste, trial and error, and copious logging, I have an Edge driver 75% working but only alpha quality.
I am stuck on capabilities.thermostatOperatingState, specifically:
local function operating_state_report_handler(self, device, cmd)
local event = nil
local state = cmd.args.operating_state"operating_state_report_handler state: ", state)

if state == 0 then – IDLE“operating_state_report_handler - IDLE”)
event = capabilities.thermostatOperatingState.thermostatOperatingState.idle()
elseif state == 1 then – HEATING“operating_state_report_handler - HEATING”)
event = capabilities.thermostatOperatingState.thermostatOperatingState.heating()
else“operating_state_report_handler - UNKNOWN → IDLE”)
event = capabilities.thermostatOperatingState.thermostatOperatingState.idle()
end“operating_state_report_handler - ready to set_field”)
device:set_field(OPERATING_STATE, state, {persist = true})“operating_state_report_handler - set_field done”)

if (event ~= nil) then"operating_state_report_handler event: ", event)

Any help appreciated.

Hello, @jaidank

As I understand, operating_state_report_handler is a handler for the attribute, right?

Are you getting an error in the logs?

If it is regarding the commands you defined like this one:

Please, check if this one works:

event = capabilities.thermostatOperatingState.thermostatOperatingState("idle")

In the Default libraries, it uses idle as a command because it imports st.zwave.CommandClass.ThermostatOperatingState. In this case, you’re calling “capabilities” and by checking the capability’s definition, we see it doesn’t have a command called idle, so, the command must point to assigning a value to the attribute thermostatOperatingState:

smartthings capabilities thermostatOperatingState -j
    "id": "thermostatOperatingState",
    "version": 1,
    "status": "live",
    "name": "Thermostat Operating State",
    "ephemeral": false,
    "attributes": {
        "thermostatOperatingState": {
            "schema": {
                "type": "object",
                "properties": {
                    "value": {
                        "title": "ThermostatOperatingState",
                        "type": "string",
                        "enum": [
                            "fan only",
                            "pending cool",
                            "pending heat",
                            "vent economizer"
                "additionalProperties": false,
                "required": [
            "enumCommands": []
    "commands": {}

Does this help? If not, please provide the error log you see in the logcat

1 Like

Thank you @nayelyz nayelyz for your prompt reply.
I think my error was:
device:set_field(OPERATING_STATE, state, {persist = true})
I have been experimenting with this but, at 1am, I changed it back to the original (below) and went to bed:
device:set_field(STATE, state, {persist = true})
This morning I found everything worked.
Next, I need to get my other thermostat working (Secure SRT321).
This is almost identical but reports a swtich state instead of thermostatOperatingState.
I am hoping to handle it with the same driver with an additional response handler.
All going well, my final step will be to figure out how best to share with the community.
Thanks, Aidan

Yes, subdrivers are very helpful for this kind of case, they allow a single driver to support different device models.
You can find some references on how to use them in the official SmartThings drivers in this repo: SmartThingsEdgeDrivers/drivers/SmartThings at main · SmartThingsCommunity/SmartThingsEdgeDrivers · GitHub

You can easily share your driver with others thanks to Channels because you can publish it there and invite people to them. Here’s a document about the sharing process:

1 Like

Hi @nayelyz
I am now working on my Secure SRT321 and am having problems.
My biggest issue is that manual heating set points done on the thermostat are not being sent to my device handler.
The documentation says this is sent to Assocition Group 4, but my driver is not seeing them.
I am seeing Thermostat Mode changes (see below, I have pretty-printed it), but my handler is not being called. Does the ‘version=3’ mean that Secure have implemented a different version to SmartThings?

2022-09-12T18:30:02.652234291+00:00 TRACE Secure SRT321 Thermostat Received event with handler unnamed
2022-09-12T18:30:02.665253416+00:00 INFO Secure SRT321 Thermostat
<ZwaveDevice: 7c7286af-12a1-43c9-ad04-50e25637e0e7 [2A] (Secure SRT321 Thermostat)>
received Z-Wave command:
2022-09-12T18:30:02.670440082+00:00 DEBUG Secure SRT321 Thermostat Secure SRT321 Thermostat device thread event handled
2022-09-12T18:30:05.422002540+00:00 TRACE Secure SRT321 Thermostat Received event with handler unnamed
2022-09-12T18:30:05.426776123+00:00 INFO Secure SRT321 Thermostat
<ZwaveDevice: 7c7286af-12a1-43c9-ad04-50e25637e0e7 [2A] (Secure SRT321 Thermostat)>
received Z-Wave command:
2022-09-12T18:30:05.431957957+00:00 DEBUG Secure SRT321 Thermostat Secure SRT321 Thermostat device thread event handled.

I don’t want to use up your bandwidth or good will on this.
I am able to send heating set point to the SRT321, and get the room temperature back (albeit by sending a GET on wake up), so I guess we will not freeze this winter.
But if you have any ideas.
So far, I am liking Edge; if only the device manufacturers would be consistent in their implementations.

Here is some excerpts from my driver:

local ThermostatMode = (require “st.zwave.CommandClass.ThermostatMode”)({ version = 3 })

local function thermostat_mode_report_handler(self, device, cmd)
local event = nil

local mode = 0 – cmd.args.mode"thermostat_mode_report_handler mode: ", mode)

[ThermostatMode.REPORT] = thermostat_mode_report_handler

Cheers, Aidan

Have you added the hub node to the thermostat’s association group 4?

The logs that you posted show the hub received ThermostatMode.SET commands:

The code excerpt you posted only defines a handler for ThermostatMode.REPORT, not ThermostatMode.SET:


Many thanks @philh30,
I will add ThermostatMode.SET handler this evening and give it a go.
I had tried to add the hub node the thermostat’s association group 4, via an Association.Set in the device_init code, but my handler did not receive any set point reports.
I am very much a newbie, I’m afraid. I can post the code if that is helpful.

Thanks again @philh30
My ThermostatMode is now working, with the app instantly updating Mode to either Off or Heat as expected.
The big thing remaining is the Association of Group 4 so I can receive handle ThermostatSetpoint.REPORT
(Group 5, for unsolicited temperature readings would also be nice, and save me having to do a Get every other wakep).
The SRT321 does have an ‘A’ (Association) but I have only managed to get that to work to associate the SSR303 (Relay) with Group 2 (Switch Binary).
As things stand, I have an SRT323 and SRT321 working well enough to manage our heating for a winter of crazy energy prices.
Thanks @philh30 and @nayelyz for your help.
Cheers, Aidan

1 Like

If you post your driver to GitHub then it will be easier to recommend changes to get your association groups set. You’ll essentially need to include something like below to be called on wakeup (ideally this code will only run once, and not on every wake up going forward). If you watch your logs, you should see the device return an Association:Report with node 1 (the hub) included in the association group.

    local hubnode = device.driver.environment_info.hub_zwave_id
    device:send(Association:Set({grouping_identifier = 4, node_ids = {hubnode}}))
    device:send(Association:Get({grouping_identifier = 4}))
    device:send(Association:Set({grouping_identifier = 5, node_ids = {hubnode}}))
    device:send(Association:Get({grouping_identifier = 5}))

Well, @philh30 , what a result; your suggestion worked perfectly (I do the Associations on the first Wake Up only).
I am now getting SetPoint changes and unsolicited temperature changes from the SRT321.
I had previously (unsuccessfully) tried Association:Set (without a Get) in device_init.
I have a GitHub account but have never really used it. I guess now is the time to learn.
I should warn you that I chickened out of implementing the SRT323 and SRT321 as sub-handlers of the more genaral community ZWave Thermostat. My two are individual standalone handlers (not ideal, I know) based on copy and paste of the community handler.

1 Like

Good job!

The Get isn’t actually necessary, but it triggers the device to send an Association:Report to confirm that the association was set properly.

Hi Aidan. I have a Hortsmann thermostat which is basically a rebranded secure SRT321. I would really appreciate it if could supply the code or link to your channel invite if you have one set up so I can try this out. All new to this and want to try and get converted over as the missus will kill me of we lose heating🤣

Hi John,
Happy to do either.
I suppose the easiest for you would be to invite you to my channel; I just need to figure out how to do that.
The fallback is to share my code with you; happy to do that also; but more work for you.
A couple of things:

  1. Double check that your Horstmann and my SRT321 share the same fingerprint:
    manufacturerId: 0x0059
    productId: 0x0003
    productType: 0x0001
  2. I never got around to repackaging both drivers into sub drivers of a single driver (not crtiical but would have been more professional).
  3. There still was an error in the logs that does not seem to impact functionality.
  4. I have not developed an Edge driver for the SSR303 relay. My thinking is that the SRT321 communicates directly with it so a ‘Z-Wave Thing’ driver will suffice.

If you check your Horstmann fingerprint, I will figure out how to do a channel invitation.

My attempts to get channel information from smartthings CLI have failed with a strange error.
I have put the latest working code in github: jaidank/SmartthingsEdge/SecureControlsSRT321


Many thanks Aidan. Yes the fingerprint matches. I was going to ask you regarding the boiler receiver driver but you have already answered that👍. I will work out how to use the code to make the edge driver. A bit more reading required but I’m sure I can work this part out. Many thanks again

Many thanks Aidan,

Figured out CLI today and got it installed and seems to be working fine so far.

I managed to sort the channel invite to work for you so here is the link it generated. You should be able to post this up in the custom drivers section for the community. I wouldn’t want to do it as you deserve all the credit for it.


1 Like

Great that you got it working John,
Not sure how I messed up the channel stuff; I initially developed the SRT323 driver (easier than the SRT321) and it is in a channel, but somehow my SRT321 driver isn’t.
Actually my CLI isn’t working that well anymore; I can list devices but not a lot of other things.
My main goal, like you, was to get the heating working before the weather got too cold (at the time I thought groovy was going to stop working on Oct 1st).
Local execution is another big bonus; I did not like being cloud dependant with the custom groovy I was using; especially for something like heating.
It’s good that somebody else benefitted; and that there is somebody I can compare notes with in future.
I bought a Secure SIR321 to control my hot water, but have not gotten around to installing it or developing an Edge driver yet.
All the best,

Hi Aidan, thanks very much for sharing your approach with this. I’ve got the same setup so will try to copy your approach.

Am. I right in thinking that the changes re Groovy won’t affect the pairing of the thermostat and boiler switch? E.g. if I don’t change anything, we’ll still be able to manually set the heating temperature?

I believe so.
I still have my SSR303 paired with a custom groovy driver (Horstmann HRT4-ZW) that I do not believe even works. My SRT321 controls the SSR303 directly via association; I am guessing that is how yours already works. So, manual adjustment will work.
While developing the Edge driver I had to reset the SRT321 several times, and had to re-associate it with the SSR303 each time.
Hopefully the above channel invitation, that @NoonDawg posted, will work for you. I can code, but the rest of the faff is a bit beyond me.
Good luck,

1 Like

Hi Aidan

I have the exact same thermostats as you and you don’t know how pleased I was to come across this post.

Have you got a channel invitation I could get onto please?



Hi @burtonjk
Happy to help in any way I can.
You say you have the same setup, both an SRT323 and SRT321/SSR303 pairing?
Yes, I have developed Edge drivers for both the SRT323 and SRT321 which work reasonably well (I have not developed an Edge driver for the SSR303 because it is controlled directly by the SRT321).
The first thing you need to do is to use the old API to get the fingerprints of both the SRT323 and SRT321 to ensure they are covered by my Edge drivers (see higher up in this thread).
While I was able to develop working Edge drivers, I am weak on all the arcane channel stuff (in my coding career I was always more focussed on the problem and the code rather than the development environment).
I think the channel invitation higher up in this thread may well work for your SRT321 (but I do not know if that is mine or NoonDawg’s).
Talk soon.