dresden-elektronik / deconz-rest-plugin

deCONZ REST-API plugin to control ZigBee devices
BSD 3-Clause "New" or "Revised" License
1.88k stars 485 forks source link

Legrand Netatmo cable outlet implementation not compliant with deconz API #5250

Closed MV1908 closed 2 years ago

MV1908 commented 2 years ago

Describe the bug

I am trying to use a Legrand Netatmo cable outlet (0 648 79) in Home Assistant via the deCONZ integration. I have successfully paired the cable outlet with the conbee ii gateway via the phoscon app. I have configured it in "fil pilote" mode via the deCONZ app (through VNC since I use the docker marthoc container). I am able to control the outlet and the heater plugged on it by sending API requests via the deCONZ REST API (PUT /sensor/xx/config ; {"mode" : "confort"} for example).

However I cant make it working in Home Assistant.

I figured out that the implementation is not compliant with the API specification (https://dresden-elektronik.github.io/deconz-rest-doc/endpoints/sensors/#supported-config-attributes_1). According to the doc, the "mode" config attribute should be one of the supported values for a "ZHAThermostat" ("off", "heat", "cool", ...), but to control the Legrand outlet you have to define the "mode" config attribute to "confort", "confort-1", "confort-2", "eco", "hors gel", or "off".

The consequence is that it could not work in Home Assistant as HA restrict the value used for "hvac_mode" (which seems to be mapped to the "mode" config attribute of the deCONZ API) to the values allowed by the API specification (using the climate component).

Steps to reproduce the behavior

Expected behavior

I think that the implementation should only allow to use the "heat" or "off" modes (the Legrand outlet is only designed to control a heater), and should allow to specify a "preset" attribute which is one of the 6 supported "fil pilote" orders ("confort", "confort -1", "confort -2", "eco", "hors gel", "off"). In HA the preset can be defined freely.

Screenshots

ha_deconz_zhathermostat_error_2 ha_deconz_zhathermostat_error_1

Environment

deCONZ Logs

No log is relevant as you can make it work with deCONZ (but using an illegal "mode" attribute)

Additional context

MV1908 commented 2 years ago

Looking at the code, the tuya implementation seems to be the way to go.

In thermostat.cpp :

const std::array<KeyValMapTuyaSingle, 2> RConfigModeValuesTuya2 = { { {QLatin1String("off"), {0x00}}, {QLatin1String("heat"), {0x01}} } };

const std::array<KeyValMapTuyaSingle, 7> RConfigPresetValuesTuya = { { {QLatin1String("holiday"), {0x00}}, {QLatin1String("auto"), {0x01}}, {QLatin1String("manual"), {0x02}}, {QLatin1String("comfort"), {0x04}}, {QLatin1String("eco"),{0x05}}, {QLatin1String("boost"), {0x06}},{QLatin1String("complex"), {0x07}} } };

Sorry, I don't have cpp skills to make a PR myself :-(

Smanar commented 2 years ago

Ha yes, this device is specific (and specific at some country), it s not a thermostat. You need a custom widget to use it in HA. Realy few users will use this kind of device (fil pilote) I dont think you will have an official widget for it.

This device is not made to use classic mode like on/off/cool/dry and ect ...

Mimiix commented 2 years ago

@Smanar So this is not a bug?

Smanar commented 2 years ago

Not for me, it s the "normalized" value for "fil pilote" device, can't use the same than for TRV or thermostat.

Mimiix commented 2 years ago

@Smanar is this something for @kane610 to fix?

Kane610 commented 2 years ago

@Smanar is this something for @Kane610 to fix?

No because this is deviating from the api documentation.I also want to avoid device specific adaptations. It's better if deconz can match it to how thermostat works

Mimiix commented 2 years ago

@Smanar @SwoopX @manup can you give opinions on if this is possible or not?

Smanar commented 2 years ago

But it s not a classic thermostat. I can't create a ZHAFilPiloteThermostat just for 1 device.

It s not possible to use custom command for this device (Manually done ofc) ?

This device work like a thermostat, it use same command "mode" it just don't use same parameter than classic thermostat, not my fault, it s the normal working mode. Perhaps tommorow we will have a thermostat with "astronomic" "magic" and "quiet" mode, I m agree, we can use "standard mode" from the API documentation, but why we can't use "custom" mode for specific device ?

On my side I just have a custom widget for this device on my third app.

I m agree, @Kane610 can't make a widget for all "exotic" device, but it s not possible to make a custom widget using HA ?

Kane610 commented 2 years ago

He can use the deConz configure service in hass and send whatever commands he wants. It can do all rest api commands

Kane610 commented 2 years ago

This device work like a thermostat, it use same command "mode" it just don't use same parameter than classic thermostat, not my fault, it s the normal working mode. Perhaps tommorow we will have a thermostat with "astronomic" "magic" and "quiet" mode, I m agree, we can use "standard mode" from the API documentation, but why we can't use "custom" mode for specific device ?

Why can't deconz translate these to standardized values?

Smanar commented 2 years ago

They are standard, but for a different working mode, it s a french technologie.

6 ordres fil pil

It s the standard value for this kind of devices

Kane610 commented 2 years ago

I meant standardized values of deconz thermostat implementation

Smanar commented 2 years ago

He can use the deConz configure service in hass and send whatever commands he wants. It can do all rest api commands

For me it s the better solution.

I meant standardized values of deconz thermostat implementation

It mean, all users will need to use a convertion table

"off" > "off" "cool" > "hors_gel" "auto" > "confort -1" "fan_only" > "confort -2"

Not something intuitive for me.

It s not possible make a plugin support all exotics devices, for me a link with a "how to do" with custom setting is the better solution.

manup commented 2 years ago

I have only little experience with thermostats. Do these custom modes represent the same as the documented thermostat modes, or do they implement a different behavior?

Smanar commented 2 years ago

Totaly different.

"confort -1" is the comfort temperature minus 1 °C "confort -2" is the comfort temperature minus 2 °C "hors gel" trigger only if temperature go under 0 °C "eco ou reduit" is the comfort temperature minus 4 °C

It s realy specific, few chance to find the same feature on other thermostats. If we make something just for this device in the API, we will need to do same tommorrow, and again, and again, and again ...

For me the better solution is the deConz configure service in hass

MV1908 commented 2 years ago

I don't understand why the different modes of operation of the Fil Pilote device could not be mapped to different presets. It seems obvious for a thermostat to only be able to order heat or cool or vent (real world modes) so this why the "mode" attribute is restricted to some values (at least in HA). For me it is a device attached to a heater so it makes sense that it should have only two modes : "heat" and "off". Then you can ask it for presets like "confort" or "eco" or whatever that makes sense to the device. It seems semantically correct.

In my understanding a request for the fil pilote thermostat should be something like :

PUT /sensor/xx/config
{
"mode" : "heat",
"preset" : "confort"
}

or

PUT /sensor/xx/config
{
"mode" : "heat",
"preset" : "eco"
}

or

PUT /sensor/xx/config
{
"mode" : "off",
"preset" : "off"
}

It seems to be the way it is done with the Tuya devices in the code of thermostat.cpp :

Modes (sticks with the standard values for a ZHAThermostat)

const std::array<KeyValMapTuyaSingle, 3> RConfigModeValuesTuya1 = { { {QLatin1String("auto"), {0x00}}, {QLatin1String("heat"), {0x01}}, {QLatin1String("off"), {0x02}} } };

const std::array<KeyValMapTuyaSingle, 2> RConfigModeValuesTuya2 = { { {QLatin1String("off"), {0x00}}, {QLatin1String("heat"), {0x01}} } };

Presets (can be defined freely)

const std::array<KeyValMapTuyaSingle, 7> RConfigPresetValuesTuya = { { {QLatin1String("holiday"), {0x00}}, {QLatin1String("auto"), {0x01}}, {QLatin1String("manual"), {0x02}}, {QLatin1String("comfort"), {0x04}}, {QLatin1String("eco"), {0x05}}, {QLatin1String("boost"), {0x06}}, {QLatin1String("complex"), {0x07}} } };

const std::array<KeyMap, 2> RConfigPresetValuesTuya2 = { { {QLatin1String("auto")}, {QLatin1String("program")} } };

const std::array<KeyMap, 4> RConfigPresetValuesTuya3 = { { {QLatin1String("both")}, {QLatin1String("humidity")}, {QLatin1String("temperature")}, {QLatin1String("off")} } };

I am trying to make those modifications in the code and will test on my side. I will make a PR if it is successful (but as I said I am not comfortable at all with c++).

After all, maybe am i influenced by that fact that HA is strict only on "mode" values and not on "preset" values but it makes sense to me as stated above.

Thanks for your time anyway and for all the previous work on supporting this device @Smanar .

Smanar commented 2 years ago

And

PUT /sensor/xx/config
{
"mode" : "heat",
"preset" : "off"
}

or


PUT /sensor/xx/config
{
"mode" : "off",
"preset" : "hors gel"
}

For me it is a device attached to a heater so it makes sense that it should have only two modes : "heat" and "off"

Precisely no, if you want to use the "heat" / "off" disable the "fil pilote" mode, you will have a on/off working mode. I m not the "fil pilote" creator, but this device is made to work with those mode (or preset). I can disable "mode" and use "preset" if you prefer, but will be the same.

And it will broke the automation on all other users, on the one that don't use HA but on the one that use deConz configure service.

For information "mode" is generally used by TRV and "preset" by thermostat, realy few devices use both. TRV have on/off mode, but thermostat are like the outlet, it s NOT just a on/off working mode, and on some thermostat the "off" just disable the display, not the heat.

Kane610 commented 2 years ago

I just got the urge to revisit the dev docs for hass and apparently I can expose custom presets https://developers.home-assistant.io/docs/core/entity/climate#presets. I will investigate this next week, no promises.

github-actions[bot] commented 2 years ago

As there has not been any response in 21 days, this issue has been automatically marked as stale. At OP: Please either close this issue or keep it active It will be closed in 7 days if no further activity occurs.

github-actions[bot] commented 2 years ago

As there has not been any response in 28 days, this issue will be closed. @ OP: If this issue is solved post what fixed it for you. If it is not solved, request to get this opened again.

Pirionfr commented 1 year ago

will it be possible, one day, to use preset for this cable outlet ?

Smanar commented 1 year ago

Yes, surely with DDF, I have started to do one, but for the moment it's not possible to mimic the needed request to change the "fil pilote mode". We can use only predefined request, need a better DDF core.

Idaho947 commented 8 months ago

Hello, zwave qubino for wire pilot are not more avalable and this cable outlet is the only way to manage it... Any news about this ? It will be also needed by the future nodoon wire pilot module.

Smanar commented 8 months ago

The device is working fine with the DDF, I m using it ATM.

Idaho947 commented 8 months ago

With wire pilot ? You have the commande ? You use HA ? I've just have on off and in pilot mode it doesn't work

Smanar commented 8 months ago

This device create 3 entries, 1 "light" entry used for on/off, and 2 sensors, a ZHAPower for power and a ZHAthermostat. You can send "mode" to the ZHAThermostat sensor, but this mode need to be enabled on the device, with the GUI on the Legrand cluster.

Idaho947 commented 8 months ago

Yes I've activate it. I'll try to exclude it (i've done it a long time ago when I was on jeedom).

Idaho947 commented 8 months ago

I reinclude it but the thermostat is unvaliable : image

The mode change works in the GUID : image

Smanar commented 8 months ago

The HA plugin have problem to support this device. Can try the REST request

curl -H 'Content-Type: application/json' -X PUT -d '{"mode":"confort"}' http://IP:PORT/api/KEY/sensors/ID/config

IP and PORT are the same used to access phoscon, KEY is an ApiKey, can use the same used by HA, and ID is the ID of the ZHAThermostat entry.

Values that can be used are

const std::array<KeyValMap, 6> RConfigModeLegrandValues = { { {QLatin1String("confort"), 0}, {QLatin1String("confort-1"), 1}, {QLatin1String("confort-2"), 2},
                                                              {QLatin1String("eco"), 3}, {QLatin1String("hors gel"), 4}, {QLatin1String("off"), 5} } };
Idaho947 commented 8 months ago

Ok I ll try but who can fix the plugin ? I think it s a better solution for eveyone no ?

Smanar commented 8 months ago

Sure you can ask on deconz plugin github, perhaps @Kane610 can make something ?

Kane610 commented 8 months ago

It would be much preferable that it is documented here what the changes related to this device is in this thread, what data can be expected from the device and some example data, that will benefit other clients as well.

Looking at the history of this thread and also the errors in the log reported on Home Assistant GitHub it might be too off to support. More details first though.

Idaho947 commented 8 months ago

Ok. @Smanar do you have something for it ?

Smanar commented 8 months ago

This device create 3 entries

    "etag": "dcda6928730bd3b345c742bdfab8a997",
    "hascolor": false,
    "lastannounced": "2023-11-06T10:56:00Z",
    "lastseen": "2023-11-06T16:03Z",
    "manufacturername": "Legrand",
    "modelid": "Cable outlet",
    "name": "Seche serviette",
    "state": {
      "on": true,
      "reachable": true
    },
    "swversion": "000a",
    "type": "Level control switch",
    "uniqueid": "00:04:74:00:00:71:13:55-01"
  },
  "3": {
    "capabilities": {
      "alerts": [
        "none",
        "select",
        "lselect"
      ]
    },
    "config": {
      "groups": [
        "0"
      ]
    },

  "5": {
    "config": {
      "on": true,
      "reachable": true
    },
    "ep": 1,
    "etag": "75c7753f4946ef2b0fc9eea20148efbe",
    "lastannounced": "2023-11-06T10:56:00Z",
    "lastseen": "2023-11-06T16:05Z",
    "manufacturername": "Legrand",
    "modelid": "Cable outlet",
    "name": "Power 5",
    "state": {
      "lastupdated": "2023-11-06T16:00:01.254",
      "power": 743
    },
    "swversion": "000a",
    "type": "ZHAPower",
    "uniqueid": "00:04:74:00:00:17:06:55-01-0b04"
  },

  "6": {
    "config": {
      "mode": "confort",
      "on": true,
      "reachable": true
    },
    "ep": 1,
    "etag": "75c7753f4946ef2b0fc9eea20148efbe",
    "lastannounced": "2023-11-06T10:56:00Z",
    "lastseen": "2023-11-06T16:05Z",
    "manufacturername": "Legrand",
    "modelid": "Cable outlet",
    "name": "Thermostat 6",
    "state": {
      "lastupdated": "2023-01-29T16:24:41.072"
    },
    "swversion": "000a",
    "type": "ZHAThermostat",
    "uniqueid": "00:04:74:00:00:17:06:55-01-0201"
  },

The first one is "light" entry, that permit to turn the device on/off id this mode is enabled The ZHAPower is just a Powermeter The ZHAThermostat is used to change the "fil pilote" mode, if this mode is enabled.

Possibles mode are :

For not french users (only used in France), the temperature is set manualy on the device, and "confort-1" mean the configured temperature minus 1 degree.

Idaho947 commented 8 months ago

Hello, any news about that ?

Smanar commented 8 months ago

I don't have impact on HA, but I hope it have the possiblities to use custom device ? On my side I have just created a switch with some code, here it's LUA code, but can use everything, the API just use REST request, easy to use.

-- Sechoir SDB
if (devicechanged['Sechoir SDB']) then
    local b = devicechanged['Sechoir SDB']
    if b == 'Confort' then
        Cmd = 'curl -H \'Content-Type: application/json\' -X PUT -d \'{"mode":"confort"}\' http://192.168.1.1:80/api/60C64A0FDF/sensors/6/config'
    elseif b == 'Eco' then
        Cmd = 'curl -H \'Content-Type: application/json\' -X PUT -d \'{"mode":"eco"}\' http://192.168.1.1:80/api/60C64A0FDF/sensors/6/config'
    else
        Cmd = 'curl -H \'Content-Type: application/json\' -X PUT -d \'{"mode":"off"}\' http://192.168.1.1:80/api/60C64A0FDF/sensors/6/config'
    end

    CmdResult = os.execute(Cmd .. ' &')
end
Idaho947 commented 8 months ago

Yes I use rest command too.