andyboeh / mediola2mqtt

Mediola MQTT Gateway
11 stars 13 forks source link

Intermediate position #17

Closed JordyThery closed 2 years ago

JordyThery commented 2 years ago

Hello,

First and foremost I'd like to thank you for this project. I've successfully set the integration up and it communicates flawlessly with my Elero Centero Home hub (rebranded Mediola 6th gen hub). I've also exposed the shutters to homekit which seems to work just fine.

I see I can send a 'stop' command without issue to have a shutter stop at a certain point. I've noticed that in the Elero Centero app I can save intermediate positions. Would this be something that is / can be supported through this integration?

Thank you for your answer.

With kind regards, Jordy Thery

andyboeh commented 2 years ago

I'm glad it works for you!

Do you have an Elero remote control, like a TempoTel 2 or similar? How do you activate an intermediate position there? The gateway itself supports about 16 different commands, so it's probably a matter of finding the correct one.

Basically, it should be possible to do what the Centero app does, if we find the correct commands.

JordyThery commented 2 years ago

Good morning,

Thanks for the quick reply!

I have a remote, it's a VariaCom 6 channel remote I believe, nothing smart or fancy.

Within the Centero app I can define two intermediate positions. Then in scenes I could set it to send a command to go up, down, intermediate 1 or intermediate 2.

If I do a GetStates I get the following: {XC_SUC}[{"type":"EVENT","adr":"FF","state":"0"},{"type":"ER","sid":"01","adr":"03","state":"1001","ts":{"m":"6295B4D6"}},{"type":"ER","sid":"02","adr":"02","state":"1001","ts":{"m":"6295B42F"}},{"type":"EVENT","adr":"06","state":"1"},{"type":"EVENT","adr":"02","state":"1"},{"type":"EVENT","adr":"07","state":"1"},{"type":"EVENT","adr":"01","state":"1"},{"type":"EVENT","adr":"04","state":"1"},{"type":"EVENT","adr":"05","state":"1"},{"type":"ER","sid":"03","adr":"04","state":"1001","ts":{"m":"6295B181"}},{"type":"ER","sid":"04","adr":"01","state":"100D","ts":{"m":"6295B58A"}},{"type":"EVENT","adr":"08","state":"1"},{"type":"EVENT","adr":"09","state":"1"},{"type":"EVENT","adr":"03","state":"0"},{"type":"EVENT","adr":"0A","state":"1"}]

Whilst in the add-on I've configured only the following:

The other addresses don't seem to do anything when triggered.

Before I got this add-on to work I used http commands to make the shutters go up and down. In that case, for one shutter with an intermediate defined I had the following:

rolluik_zijkant_omhoog: 'curl -k "http://192.168.1.211/command?XC_USER=user&XC_FNC=doAction&ID=05"' rolluik_zijkant_midden: 'curl -k "http://192.168.1.211/command?XC_USER=user&XC_FNC=doAction&ID=16"' rolluik_zijkant_omlaag: 'curl -k "http://192.168.1.211/command?XC_USER=user&XC_FNC=doAction&ID=11"'

The only issue I had with this way of doing things is that I did not have a reported state and when exposed to HomeKit for example I had multiple toggles for the same shutter.

With kind regards, Jordy Thery

andyboeh commented 2 years ago

Ah, that's interesting. Looks like the intermediates are not actually defined by Elero but "faked" by the Mediola. Probably they send Up, wait a bit of time and then send Stop. However, my blinds do not report back a percentage value when moving or stopped, I only know they are moving or stopped.

If you run these commands while the add-on is running, do you see any state changes for the blinds?

JordyThery commented 2 years ago

Hi,

Unfortunately not. I get a {XC_SUC}{} response when running the http command. Nothing happens in the add-on. (neither do the other doAction commands to go up or down).

If I refresh the devices tab in the Centero Home app I can see an icon that does report it being up, down or intermediate.

Setting it to intermediate in the Centero app also doesn't make anything happen in the add-on.

With kind regards, Jordy Thery

andyboeh commented 2 years ago

That doesn't make it easier, then.

Do you get feedback while your blind is moving within Home Assistant, i.e. does the UDP feedback work correctly? Remember that you need to change the port to 1901 on a v6 gateway. If not, then we should fix that first, maybe feedback works then?

JordyThery commented 2 years ago

Hi,

Yes, I've set the port to 1901 and the feedback works there (e.g if I click the up button within HomeAssistant the shutter goes up and the correct status is received by mqtt).

I guess that the add-on uses a different command set to trigger the up / down / stop and therefore doesn't detect the doAction commands I send with http?

If I run a XC_FNC=GetAll command I get the following result (though for example the RF commands are from me messing about):

{XC_SUC}[{"sys":"GROUP","id":"FF","active":"0","triggerids":"","actionids":""},{"sys":"TASK","id":"01","days":"1111111","time":"05:15","dateStart":"2000-00-00","dateEnd":"2000-00-00"},{"sys":"ACTION","id":"01","type":"ER","code":"0109","rf":"00","ir":"00"},{"sys":"GROUP","id":"06","active":"1","triggerids":"07","actionids":"10"},{"sys":"GROUP","id":"02","active":"1","triggerids":"02","actionids":"04010315"},{"sys":"ACTION","id":"03","type":"ER","code":"0409","rf":"00","ir":"00"},{"sys":"ACTION","id":"04","type":"ER","code":"0209","rf":"00","ir":"00"},{"sys":"TASK","id":"02","days":"1111111","time":"22:00","dateStart":"2000-00-00","dateEnd":"2000-00-00"},{"sys":"GROUP","id":"07","active":"1","triggerids":"08","actionids":"11"},{"sys":"ACTION","id":"05","type":"ER","code":"0188","rf":"00","ir":"00"},{"sys":"ACTION","id":"15","type":"ER","code":"0309","rf":"00","ir":"00"},{"sys":"GROUP","id":"01","active":"1","triggerids":"01","actionids":"05061202"},{"sys":"EVENT","id":"05","active":"1","type":"IRCODE","code":"190824050004000000D210"},{"sys":"ACTION","id":"06","type":"ER","code":"0308","rf":"00","ir":"00"},{"sys":"TASK","id":"03","days":"1111100","time":"05:15","dateStart":"2000-00-00","dateEnd":"2000-00-00"},{"sys":"TASK","id":"04","days":"0000011","time":"08:00","dateStart":"2000-00-00","dateEnd":"2000-00-00"},{"sys":"ACTION","id":"07","type":"ER","code":"0308","rf":"00","ir":"00"},{"sys":"ACTION","id":"02","type":"ER","code":"0208","rf":"00","ir":"00"},{"sys":"ACTION","id":"08","type":"ER","code":"0108","rf":"00","ir":"00"},{"sys":"ACTION","id":"09","type":"ER","code":"0209","rf":"00","ir":"00"},{"sys":"ACTION","id":"0A","type":"ER","code":"0208","rf":"00","ir":"00"},{"sys":"GROUP","id":"04","active":"1","triggerids":"05","actionids":"0A080B0C"},{"sys":"ACTION","id":"0B","type":"ER","code":"0308","rf":"00","ir":"00"},{"sys":"ACTION","id":"0C","type":"ER","code":"0408","rf":"00","ir":"00"},{"sys":"ACTION","id":"0D","type":"ER","code":"0109","rf":"00","ir":"00"},{"sys":"GROUP","id":"05","active":"1","triggerids":"06","actionids":"090D0E0F"},{"sys":"ACTION","id":"0E","type":"ER","code":"0309","rf":"00","ir":"00"},{"sys":"ACTION","id":"0F","type":"ER","code":"0409","rf":"00","ir":"00"},{"sys":"ACTION","id":"10","type":"ER","code":"0108","rf":"00","ir":"00"},{"sys":"ACTION","id":"11","type":"ER","code":"0109","rf":"00","ir":"00"},{"sys":"ACTION","id":"12","type":"ER","code":"0408","rf":"00","ir":"00"},{"sys":"ACTION","id":"13","type":"ER","code":"0308","rf":"00","ir":"00"},{"sys":"ACTION","id":"14","type":"ER","code":"0309","rf":"00","ir":"00"},{"sys":"ACTION","id":"16","type":"ER","code":"010B","rf":"00","ir":"00"},{"sys":"EVENT","id":"06","active":"1","type":"IRCODE","code":"190824050005000000D211"},{"sys":"EVENT","id":"07","active":"1","type":"IRCODE","code":"190824050007000000D221"},{"sys":"EVENT","id":"08","active":"1","type":"IRCODE","code":"190824050004000000D220"},{"sys":"GROUP","id":"08","active":"1","triggerids":"09","actionids":"13"},{"sys":"EVENT","id":"09","active":"1","type":"IRCODE","code":"190824050003000000D22C"},{"sys":"GROUP","id":"09","active":"1","triggerids":"0A","actionids":"14"},{"sys":"EVENT","id":"0A","active":"1","type":"IRCODE","code":"190824050003000000D286"},{"sys":"GROUP","id":"03","active":"0","triggerids":"03","actionids":"07"},{"sys":"GROUP","id":"0A","active":"1","triggerids":"","actionids":"16"}]

With kind regards, Jordy Thery

andyboeh commented 2 years ago

Yes, I don't really know what the Mediola sends over UDP and what not. For your use-case, we would need to poll the Mediola for the current state - for my use-case relying on the UDP packets for the state changes is fine. That's one of the things on my todo list that I haven't had the time to implement to.

I'm planning a bigger rewrite anyway, but that's going to take a few months. I don't know how good your Python skills are, but you could add a periodic call to XC_FNC=GetStates and parse the results to update the state.

JordyThery commented 2 years ago

Hi,

Thanks for the quick replies!

I'm not a coder at all, happy that I got the add-on running in the first place. I'll keep an eye on this repository and update accordingly. Basics work mighty fine, better than the http commands.

I'll close this in the meanwhile.

Thank you for all your efforts. Drop a donation link somewhere; I'll be sure to buy you a drink. :-)

With kind regards, Jordy Thery

rorso commented 2 years ago

If I read your communication correct, then you are triggering 3 predefined actions to get your shutters moving:

up = 05
intermediate = 16
down = 11

Tha actions in your config would then send the following commands (channel 01):

up: 0188
intermediate: 010B
down: 0109

You could try whether you can simulate this without predefined actions by directly issuing the commands (channel 01):

http://192.168.1.211/command?XC_USER=user&XC_FNC=SendSC&type=ER&data=0188
http://192.168.1.211/command?XC_USER=user&XC_FNC=SendSC&type=ER&data=010B
http://192.168.1.211/command?XC_USER=user&XC_FNC=SendSC&type=ER&data=0109

I'm not sure about the 0188, as I think this could be 0108 instead. This would match the API documentation for the commands "3s Up" (long-press Up) = 08, "Double tap Down" = 0B and "3s Down" (long-press down) = 09.

That's exactly what my TempoTel2 and my Mediola V5 uses to do a "full up", "intermediate position" and "full down". If learned, my bilnds do support a "ventilation position" with command "0A" on the channel which is marked "Double tap Up".

The "intermediate" may only work correctly when starting from the "full open" position.

JordyThery commented 2 years ago

Hello @rorso,

Yes, those three http commands do trigger the shutters to go up, down and intermediate. Nothing is visible in the mediola to mqtt log though.

Perhaps because I only defined type: ER adr: '01' name: Rolluik zijkant

Pressing the up or down button from within the HomeAssistant devices does show up in the add-on log.

With kind regards, Jordy Thery

rorso commented 2 years ago

@JordyThery

madiola2mqtt is a middleware to a middleware and thus depends on a couple of assumptions.The entry in the config does create the necessary structures on MQTT so 3rd-party software (HA) can place commands there. As such this configuration is sufficient so far.

HomeAssistant has it's own configuration for dealing with "cover" devices and the HA-MQTT Addon uses the "device properties" to place "payload" information for each possible action (as defined in the HA device properties) in the corresponding MQTT path for your in mediola2mqtt configured shutters.

These payloads default to strings "open", "close", "stop" HA-MQTT cover

And these three are as much as this component does offer (kind of).

mediola2mqtt reads these payloads and does a translation to issue just such URLs to your Mediola device, containing the necessary channel and "command byte".

Currently these command translations are set to

open --> 01
close --> 00
stop --> 02

Depending on your motor devices this may or may not open and close your shutters as expected. @andyboeh found this working well. I had to change the translations for open and close to other commands to get my blinds working.

Currently this translation is not easily configurable and must be done in the program code, so I change the source code for my own installation to fit this change. But since this collides with the original and working code from @andyboeh, we cannot simply merge our sources.

To make more functions available in your preferred automation app, the app-native device configuration must offer a suitable property that you can use and some kind of button/switch/slider to operate that. This then will put a suitable "payload" into MQTT and THIS has to be translated by mediola2mqtt to the proper command on your Mediola.

Since mediola2mqtt currently knows of just the three payloads mentioned above and no other, triggering the "intermediate" state would need to extend the payload interpreter within mediola2mqtt and probably the HA-MQTT and/or HA Device configuration to offer some kind of GUI and property that triggers this payload to start with.

Simply exposing more commands from the Mediola API to the MQTT payload however does not help with HomeAssistant, as this knows of no property "intermediate" or "ventilation". HA-Cover Either these have to be additional buttons or the "set_position" number (0 - 100%) has to be translated into the needed "intermediate" so that moving the slider halfways would trigger the "intermediate" command.

So getting in the "intermediate" in here touches more than just mediola2mqtt.

Other MQTT capable GUIs may offer more device properties out of the box. Exposing more of the Mediola API commands to get triggered by suitable "payloads" this does make sense anyway.

I will try make a proposal how this can be done without breaking current installations. This may take some time.

andyboeh commented 2 years ago

@rorso Thanks for this detailed explanation, I couldn't have done it better. My idea was to create template buttons in HA that trigger the intermediate position via HTTP commands. But this makes only sense if mediola2mqtt gets feedback about the current state, otherwise it would run out of sync.

It's a bit sad I can't invest more time in this, I have quite a few ideas on how to make it better. Above all, I would like to turn it into a custom component for HA, eliminating the need for MQTT.

JordyThery commented 2 years ago

Hello,

thank you both for the explanations, much clearer now.

Being able to slide it to 50% to set the intermediate would indeed be a nice way to do it, especially since this would then also translate to HomeKit.

Regardless, I’ll patiently keep an eye on this repository wondering what the future will bring. :-)

For now I just enabled my HTTP commands specifically for the few shutters’s intermediate position and using this addon for the rest.

Thanks once again!

With kind regards, Jordy Thery

rorso commented 2 years ago

@JordyThery Can you please try the following changes in mediola2mqtt.py

locate the 'blinds' in on_message. Original Source ~ line 61. Replace the if msg.payload processing with this:

            if msg.payload == b'open':
                if dtype == 'RT':
                    data = "20" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "01"
                else:
                    return
            elif msg.payload == b'close':
                if dtype == 'RT':
                    data = "40" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "00"
                else:
                    return
            elif msg.payload == b'stop':
                if dtype == 'RT':
                    data = "10" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "02"
                else:
                    return
            # extended commands
            elif msg.payload == b'down':
                if dtype == 'RT':
                    data = "40" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "00"
                else:
                    return
            elif msg.payload == b'up':
                if dtype == 'RT':
                    data = "20" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "01"
                else:
                    return
            elif msg.payload == b'longup':
                if dtype == 'RT':
                    data = "20" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "08"
                else:
                    return
            elif msg.payload == b'longdown':
                if dtype == 'RT':
                    data = "40" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "09"
                else:
                    return
            elif msg.payload == b'doubleup':
                if dtype == 'RT':
                    data = "20" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "0A"
                else:
                    return
            elif msg.payload == b'doubledown':
                if dtype == 'RT':
                    data = "40" + adr
                elif dtype == 'ER':
                    data = format(int(adr), "02x") + "0B"
                else:
                    return
            elif spayload.isnumeric():
                #tilt
                if dtype == 'ER':
                    if int(spayload) > 0:
                        data = format(int(adr), "02x") + "0A"   #double tap up
                    else:
                        data = format(int(adr), "02x") + "0B"   #double tap down
                else:
                    return
            else:
                print("Wrong command: " + str(msg.payload))
                return

To get the enhanced device into Home Assistant, the MQTT Autodiscovery Template has to be enhanced too. Locate the payload structure and change it to this one ~ line 184:

            payload = {
              "command_topic" : topic + "/set",
              "tilt_command_topic" : topic + "/set",
              "tilt_min" : 0,
              "tilt_max": 1,
              "tilt_closed_value" : 0,
              "tilt_opened_value" : 1,
              "tilt_command_template" : """
                {% set tilt = state_attr(entity_id, "current_tilt_position") %}
                {{ tilt }}""",
              "payload_open" : "longup",
              "payload_close" : "longdown",
              "payload_stop" : "stop",
              "optimistic" : True,
              "device_class" : "blind",
              "unique_id" : mediolaid + '_' + identifier,
              "name" : name,
              "device" : {
                "identifiers" : deviceid,
                "manufacturer" : "Mediola",
                "name" : "Mediola Blind",
              },
            }

Please have a close look at the payload_open and payload_close entries and match them to your proper command as in the payload processing. Originally there have been open and close AKA up and down (button on your remote).

The tilt_open and tilt_close are set to boolean operation (0,1) instead of 0-100 here to achieve a clear match to a single command 0A, 0B.

With this enhanced AutoDiscover, HA presents a more complex device with additional buttons, if you first tap on the device line.

You may want to change the device_class if your devices are no "blinds".

See: https://www.home-assistant.io/integrations/cover.mqtt/ and https://developers.home-assistant.io/docs/core/entity/cover

With this I could access both the intermediate (0) and the tilt position (1) with my Elero blinds - for devices that have them learned via the remote.

I'm still struggling to get this template into the regular config (as override values) without breaking anything. This way one can adjust this without touching the source.