Adding a bTicino Smarther2 Thermostat using the openHAB Netatmo binding

Hi everyone,

this is my first post, so I hope to match the Help Us Help You guidelines as closely as possible.


TL;DR - A Room thing added using the Netatmo openHAB binding to support a bTicino Smarther2 thermostat never leaves the UNKNOWN state.
In the first place, bridge settings make it unclear to me whether Room is the correct thing type to use as parent of the Thermostat.


Context

As mentioned in the topic title, I own a bTicino Smarther2 thermostat, which is natively integrated with the Netatmo home automation system as well as with the Apple Homekit interface. As per the vendor instructions, I have set it up in my home network using the Legrand/Netatmo/bTicino Home + Control app, which guides through the process of adding it as a Homekit bridge and binds it to a Netatmo account, allowing full control and scheduling both from the local network and while away (through the cloud), both from Apple Home and from the Home + Control app. No problem so far.

With the goal of adding the thermostat to my openHAB instance, I browsed through all possibly relevant add-ons, finding out the following:

  • BTicinoSmarther: this is meant to work with an older generation of the same thermostat (Smarther X8000), and I know for sure that is not relevant because I also own one such thermostat and I could successfully add it to openHAB using a bridge connecting to the Works with Legrand developer API. The Smarther2 generation uses a completely different interface and API (therefore binding).
  • OpenWebNet (BTicino/Legrand): this is meant to operate with MyHOME BUS or ZigBee devices supporting the OpenWebNet protocol; to the best of my knowledge, the bTicino Smarther2 thermostat does not support any such protocols.
  • Netatmo has therefore been my final choice; the rest of this post only considers this binding.

Problem statement

Adding the Smarther2 thermostat using the Netatmo binding fails for an apparently unknown reason. This is what I have tried so far:

  1. Following the instructions, I could successfully register an application on the Netatmo developer portal and add a Netatmo Account thing to my openHAB instance, which I have also authorized with Netatmo Connect and is now in the ONLINE state
  2. I have retrieved my home_id by querying the “live” Netatmo APIs from the Home+Control API Documentation page and I could successfully add a Home thing to my openHAB, which is also in the ONLINE state

Doubts arose at this point, because the Home + Control API seems to organize a house into homes, rooms and modules, and the Netatmo binding documentation confirms that Thermostat devices are “placed in a given room”. Therefore:

  1. I have retrieved the id of the room that contains the Smarther2 thermostat and tried to add it as a Room thing, but this has always been stuck in the UNKNOWN state. After checking several times the correctness of the retrieved room id I even tried, improperly, to use something different as the Thing ID for the Room thing (e.g., the MAC address of the Thermostat itself), but nothing changed of course.

So, this is the first problem: the Room thing never leaves the UNKNOWN state.
Investigating further, I have realized that a Netatmo Thermostat thing cannot even be bound to a Room bridge (such bridge is not even listed when adding a Thermostat thing), but can be bound to a Relay bridge instead, as also confirmed in this post. I found this rather surprising because Relays and Thermostats together do not expose any channels that have anything to do with temperatures or furnace status, but I have made an attempt to go this way:

  1. I have added a fictitious Relay thing pointing to the MAC address of the Smarther2 thermostat (I know that this is unexpected to work, but actually I do not own any relays), and it stuck on the UNKNOWN state as well, this time expectably.

And so, here is the second problem: what kind of thing should I use in the first place to add my Smarther2 thermostat, given that I do not own any relays or valves but just the thermostat itself ?

My heartfelt thank you goes to anyone who dares to read so far and propose hints to address this issue.


Technical information

  • openHAB version: 3.4.1 (release build)
  • Platform: official Docker image, with network_mode set to host
  • Host: Raspberry Pi 4B running Raspbian GNU/Linux 11 (bullseye), 32-bit version (it is unlikely to be relevant, but the arm_64bit option is set to 1 to work around a completely independent issue)

Investigations so far

Performed searches

Click here to expand

Documentation aside, I have browsed through the community forum in search of a similar case, finding some hints but no true solutions:

Troubleshooting steps

Click here to expand
  • Restarting openHAB (actually its Docker container) does not help.
  • Restarting the org.openhab.binding.netatmo bundle from the Karaf openHAB console does not help.
  • The Karaf openHAB console does not output anything sensitive when the Room thing is disabled and enabled again:
19:44:19.886 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'netatmo:room:d82368ebbd:39f86e0de6' changed from UNINITIALIZED to UNINITIALIZED (DISABLED)
19:44:23.717 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'netatmo:room:d82368ebbd:39f86e0de6' changed from UNINITIALIZED (DISABLED) to INITIALIZING
19:44:23.728 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'netatmo:room:d82368ebbd:39f86e0de6' changed from INITIALIZING to UNKNOWN
  • The same happens if ancestor things (Home, Account) are disabled and enabled again (remember that they always correctly reach the ONLINE state anyway).
  • The following messages are sometimes emitted:
19:45:47.015 [WARN ] [b.core.thing.binding.BaseThingHandler] - Handler ApiBridgeHandler of thing netatmo:account:ae4c66b9e8 tried checking if channel monitoring#request-count is linked although the handler was already disposed.
19:45:47.176 [WARN ] [b.core.thing.binding.BaseThingHandler] - Handler DeviceHandler of thing netatmo:home:ae4c66b9e8:d82368ebbd tried accessing its bridge although the handler was already disposed.

Apparently, these have no adverse effects on the operation of the affected Account and Home things. There is a long thread discussing this issue, among others, but it seems to relate to authorization failures, which I am not experiencing. Another thread discusses queued callbacks and, again, this is not my case as I am not using callbacks at all.
To be honest, these warnings do not worry me very much because the Room thing state has always been UNKNOWN regardless of them being issued or not.

  • Setting the log level for the org.openhab.binding.netatmo logger to TRACE shows the following (again when disabling and re-enabling the Room thing; sensitive information edited):
19:53:48.674 [DEBUG] [g.netatmo.internal.action.RoomActions] - Netatmo RoomActions service created
19:53:48.681 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'netatmo:room:d82368ebbd:39f86e0de6' changed from UNINITIALIZED (DISABLED) to INITIALIZING
19:53:48.687 [DEBUG] [etatmo.internal.handler.ModuleHandler] - Initializing handler for thing netatmo:room:d82368ebbd:39f86e0de6
19:53:48.691 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'netatmo:room:d82368ebbd:39f86e0de6' changed from INITIALIZING to UNKNOWN
19:53:50.693 [TRACE] [tmo.internal.handler.ApiBridgeHandler] - executeUri GET  https://api.netatmo.com/api/homesdata?home_id=.........
19:53:50.765 [TRACE] [tmo.internal.handler.ApiBridgeHandler] - executeUri returned : code [200 OK] body {"body":{"homes":[{"id":".........","name":".........","altitude":149,"coordinates":[.........,.........],"country":"IT","timezone":"Europe\/Rome","rooms":[{"id":".........","name":".........","type":"corridor"}],"schedules":[.........],"name":".........","default":false,"away_temp":12,"hg_temp":7,"id":".........","selected":true,"type":"therm"}]}],"user":{"email":".........","language":"it-IT","locale":"it-IT","feel_like_algorithm":0,"unit_pressure":0,"unit_system":0,"unit_wind":0,"id":"........."}},"status":"ok","time_exec":0.01612710952758789,"time_server":1676746430}
19:53:50.772 [TRACE] [tmo.internal.handler.ApiBridgeHandler] - executeUri GET  https://api.netatmo.com/api/homestatus?home_id=.........
19:53:50.824 [TRACE] [tmo.internal.handler.ApiBridgeHandler] - executeUri returned : code [200 OK] body {"status":"ok","time_server":1676746431}
19:53:50.828 [DEBUG] [.handler.capability.RefreshCapability] - Module refreshed, next one in 180 s

So, no errors at all in contacting the APIs and successfully returned home topology (including a room with its id).

  • Discovery of Netatmo things, as mentioned in the documentation, does not produce any results, even when the scan is manually started from the Things/Netatmo binding page (/settings/things/add/netatmo).

Four additional pieces of information:

  1. Purposefully setting a wrong ID for the Netatmo Home thing makes a difference, as the thing status turns to UNKNOWN, an exception is raised and the following error is emitted on the console (with TRACE logging level):

    17:23:47.888 [TRACE] [tmo.internal.handler.ApiBridgeHandler] - executeUri GET  https://api.netatmo.com/api/homesdata?home_id=EDITED_WRONG_HOME_ID
    17:23:47.890 [WARN ] [b.core.thing.binding.BaseThingHandler] - Handler ApiBridgeHandler of thing netatmo:account:ae4c66b9e8 tried checking if channel monitoring#request-count is linked although the handler was already disposed.
    17:23:47.951 [TRACE] [tmo.internal.handler.ApiBridgeHandler] - executeUri returned : code [403 Forbidden] body {"error":{"code":13,"message":"Forbidden access to home"}}
    17:23:47.953 [DEBUG] [tmo.internal.handler.ApiBridgeHandler] - Error deserializing payload from error response
    org.openhab.binding.netatmo.internal.api.NetatmoException: Rest call failed: statusCode=OPERATION_FORBIDDEN, message=
    Forbidden access to home
    

    Fixing the Home thing ID immediately restores normal behavior as well as the ONLINE status.
    On the other hand, setting a wrong ID for the Netatmo Room thing does not make any differences: no errors are emitted on the console and the thing status is always UNKNOWN.

  2. While the Account and Home things have a quite long ID consisting of 24 characters (apparently hexadecimal, therefore 12 bytes), the Room thing has a shorter one consisting of 10 digits (but this could just be a coincidence and they may still be hexadecimal characters, therefore 5 bytes).
    Hence, I have tried to

    • pad the Room ID with initial spaces to reach 24 total characters
    • pad the Room ID with initial zeros to reach 24 total characters
    • convert the Room ID to an hexadecimal value
    • apply the same initial paddings to the converted value to reach 24 total characters

    None of the above attempts has succeeded: the Room thing is always in the UNKNOWN status and no errors are emitted.

  3. According to the documentation, the openhab:netatmo showIds console command should

    I have 3 things configured for the Netatmo binding (the Account, a Home and a Room), so I would expect at least the last two to be reported, but not even the Home is reported instead:

    openhab> openhab:netatmo showIds
    Account bridge: Netatmo - Account
    openhab>
    
  4. Browsing through the source code of the Netatmo binding, it seems that the showIds command is defined in this class.
    In turn, this invokes the identifyAllModulesAndApplyAction method of the ApiBridgeHandler, which is defined here.
    This method queries different API sections to scan for various thing types, including homes and rooms.
    Unfortunately, I could not figure out how the getRooms method that is leveraged in that scan could return significant information. Its only declarations appear here, where getRooms is defined as a simple accessor method:

    public NAObjectMap<HomeDataRoom> getRooms() {
        return rooms;
    }
    

    and here, where getRooms is again an accessor method to a possibly local data structure:

    public NAObjectMap<Room> getRooms() {
        NAObjectMap<Room> localRooms = rooms;
        return localRooms != null ? localRooms : new NAObjectMap<>();
    }
    
    

    Indeed, I was unable to find any places where the rooms map, which I expected to store Room data, is populated instead of being accessed.

As an extreme candidate conclusion, I am starting to think that the Room thing may be only partially implemented, thus impairing addition of a Thermostat altogether (which at present cannot be bound to a Room-type bridge anyway).
Yet, I am still much more inclined to think that I have overlooked the true data flow in the code, especially considering that other users are seeing Room things at least temporarily switching to the ONLINE status.

Have you tried to make use of the discovery function?
BTW it think your device type is not currently handled by this version of the binding. It is able to work with boiler plug (NAPlug), Netatmo Thermostat (NATherm1) and valves (NRV) while your BTicino seems to be BNS - so the binding does not recognize it.

Thank you very much @glhopital.

Yes, I have, in two ways:

  1. By clicking on the Scan button in the Add new thing/Netatmo binding screen: in a few seconds the scroll bar reaches 100% but no devices are detected.
  2. By running the following command in the Karaf openHAB console (assuming it is the correct one; I have inferred the binding ID from the source code):
    openhab> openhab:discovery start netatmo
    openhab>
    

This is confirmed by the Netatmo API documentation.
You definitely know better than me, but this post (and the following two) imply that this kind of thermostat cannot be controlled in any other ways than through the cloud. Since you have considered discovery as an option, I am assuming that currently supported NA* devices are not restricted to this cloud-managed-only architecture.

So, in case this model is really still unsupported (I was also considering the humble option of contributing but, to be honest, I will hardly be able to :relieved:) and considering the possible similarity of the Netatmo API with the former Legrand one for which the BTicinoSmarther binding exists, do you think that future development may likely consider this improvement?

The most I can think of in the meantime is to resort to less elegant workarounds (scripting, HTTP binding, etc.) to access the thermostat data.

Unfortunately, I asked if you tried discovery because if nothing is discovered, it is not supported.
I think that the binding could be extended to handle the BNS thermostat type through Netatmo cloud API but without the device itself, I’ll not be able to do it - so you’ve got, either to rely on HTTP binding, either find somebody who is able to implement it.
But also, what is wrong with the BTicinoSmarther binding ?

Understood, thank you.

Sounds absolutely reasonable.

The BTicinoSmarther binding implements support for the Smarther legacy V2.0 API specification which differs, even in terms of abstract house model, from the Netatmo Home+Control one. The complete picture follows:

According to the instructions, initialization of a bTicino Smarther2 thermostat (which I am trying to onboard in openHAB) happens by using the Home+Control app, which binds it to the Netatmo Connect ecosystem with the associated APIs, therefore expected to be supported by the Netatmo binding.
Only the first-generation bTicino Smarther X8000, which is initialized by means of the legacy bTicino Thermostat app, is programmed to use the Smarther legacy V2.0 APIs, which are supported by the BTicinoSmarther binding instead (confirmed working, as I also own one such thermostat).

To be honest, I did not attempt to initialize the Smarther2 using the legacy app, but I wouldn’t expect promising results given that API calls are likely hardcoded in the thermostat firmware and differ between the two generations. Not to mention that they are legacy and, therefore, with uncertain lifetime.

Quick update: I am currently seeking for a custom solution to control the Smarther2 unit by using an external tool to stitch calls to the Netatmo Home+Control API with an openHAB thing, and corresponding items.

There it goes: I have finally written a little Python tool to expose the functions of the BTicino Smarther2 Wi-Fi thermostat via the MQTT protocol. It supports publishing the main thermostat state values (temperature, humidity), as well as receiving commands to set the target temperature and operational mode. By using the openHAB MQTT binding it is possible to have such state information, as well as control commands, available inside openHAB in the form of items.
The tool is wrapped inside a Docker container mainly to eliminate dependencies on host-side Python packages, to ease running it as a system service, to check its health and to restart it in case of failure.

The tool is available on Github and is comprehensively documented: GitHub - maxonthegit/smarther2mqtt: A Docker container to expose the functions of a BTicino Smarther2 Wi-Fi thermostat to an MQTT broker, hence to openHAB

Although this is not a native integration into openHAB, it pretty much fully addresses my needs, therefore I am marking the topic as solved.

2 Likes