Skip to content
This repository has been archived by the owner on Apr 11, 2023. It is now read-only.

Other device RF 433MHz #13

Open
Litosaragon opened this issue May 20, 2022 · 4 comments
Open

Other device RF 433MHz #13

Litosaragon opened this issue May 20, 2022 · 4 comments

Comments

@Litosaragon
Copy link

Hello,
I have a Mediola gateway v5 with some devices:

  • 2 Elero Blind motors, that i can control via home assistant and mediola2mqtt
  • 2 generic 433Mhz devices that i control via IQCONTROL app of Mediola.

Is there any possibilitie to include this type of 433MHz devices in the mediola2mqtt plugin?

Thanks in advance.

@andyboeh
Copy link
Owner

Of course, but you will have to figure out how it works. The first steps is to figure out the device type:
http://mediola.lan/command?XC_FNC=GetStates (replace mediola.lan by your Mediola's address).

@rorso
Copy link

rorso commented May 20, 2022

I have done that and the "true generic" 433 devices do not show up in the "GetStates" as they do not have a "state" to remember. They are one-shots without ackknowledge. Instead they are sent ad-hoc as an "IR" device, like a TV remote. Obviously this triggers ALL possible air channels simultaneously.

So you first have to grab the code that is sent by watching the UDP traffic while learnng the device.

Next you have to add that code into the config file like this one:

- type: IR
  name: Teichlicht1
  on_value: >-
    19080081000500190500CC00E001A400E101A401B900CC01B900C.....
  off_value: >-
    19080081000500190500CC00E101A400E001A401BA00CC01B800C....

You may be lucky that the device is InterTechno compatible so you would not need the entire binary code but can use the "IT" routine and just the device codes:

- type: IT
  name: Sternenlampe
  on_value: 3C5B1490
  off_value: 3C5B1480

It depends how you were able to learn the device into the Mediola V5.

But I had to extend the core application to allow for these configuration extensions.

@Litosaragon
Copy link
Author

Thanks for the quick reply.

Yes you are correct, it dont show up any "getstate".

My 433Mhz device is NOT an Intertechno so i have to put the entire code in the config file. Where is this config file placed?. I have all the codes for the learning procces of MEdiola v5 IQcontrol app.

I have done that and the "true generic" 433 devices do not show up in the "GetStates" as they do not have a "state" to remember. They are one-shots without ackknowledge. Instead they are sent ad-hoc as an "IR" device, like a TV remote. Obviously this triggers ALL possible air channels simultaneously.

So you first have to grab the code that is sent by watching the UDP traffic while learnng the device.

Next you have to add that code into the config file like this one:

- type: IR
  name: Teichlicht1
  on_value: >-
    19080081000500190500CC00E001A400E101A401B900CC01B900C.....
  off_value: >-
    19080081000500190500CC00E101A400E001A401BA00CC01B800C....

You may be lucky that the device is InterTechno compatible so you would not need the entire binary code but can use the "IT" routine and just the device codes:

- type: IT
  name: Sternenlampe
  on_value: 3C5B1490
  off_value: 3C5B1480

It depends how you were able to learn the device into the Mediola V5.

But I had to extend the core application to allow for these configuration extensions.

@rorso
Copy link

rorso commented May 23, 2022

Btw. I did a fork of this project so if you have troubles with any of my code, don't bother @andyboeh about it, but complain with me. I just don't want to lure you away as this is bad behaviour.

As soon as you have installed the "Mediola to MQTT" as Add-On, you find it via HA:

settings / add-ons / Mediola to MQTT
2022-05-23_17-02

However, to make the program accept this configuration and do as intended, you have to make several additions to the current codebase.

1) change the config.json add the following block (i did before "buttons")

      "switches": [
        {
        "type": "match(IT|IR)?",
        "adr": "str?",
        "name": "str?",
        "on_value": "str?",
        "off_value": "str?"
        }
      ],

2) Enhance mediola2mqtt.py

Most of my extension is bluntly stolen from other parts of this code, tweaked a little for the new naming, so all credit goes to @andyboeh who did all of the brain work :-)

Within the on_message function add support for the switches (I did after the for ii in range(0, len(config['blinds'])): block):

    for ii in range(0, len(config['switches'])):
        #currently only Intertechno and IR (= "other")
        if dtype != 'IT' and dtype != 'IR':
            continue

        # get address of configured switch
        if 'adr' in config['switches'][ii]:
            cadr = config['switches'][ii]['adr']
        elif dtype == "IT":
            #try to calculate switch address from on_value for auto-learn IT switches, if adr is missing
            cadr = get_IT_address(config['switches'][ii]['on_value'])
        elif dtype == "IR":
            #try to calculate switch address from name for OR switches, if adr is missing
            cadr = get_IR_address(config['switches'][ii]['name'])

        if dtype == config['switches'][ii]['type'] and adr == cadr:
            if isinstance(config['mediola'], list):
                if config['switches'][ii]['mediola'] != mediolaid:
                    continue

            if msg.payload == b'ON':
                if 'on_value' in config['switches'][ii]:
                    data = config['switches'][ii]['on_value']
                elif dtype == "IT" and len(adr) == 3:
                    # old family_code + device_code, A01 - P16
                    data = format((ord(adr[0].upper()) - 65),'X') + format(int(adr[1:]) - 1,'X') + 'E'
                else:
                    print("Missing on_value and unknown type/address: " + dtype + "/" + adr)
                    return
                #print("on_value: = " + data)
            elif msg.payload == b'OFF':
                if 'off_value' in config['switches'][ii]:
                    data = config['switches'][ii]['off_value']
                elif dtype == "IT" and len(adr) == 3:
                    # old family_code + device_code
                    data = format((ord(adr[0].upper()) - 65),'X') + format(int(adr[1:]) - 1,'X') + '6'
                else:
                    print("Missing off_value and unknown type/address: " + dtype + "/" + adr)
                    return
                #print("off_value: = " + data)
            else:
                print("Wrong command")
                return

            if dtype == 'IT':
                payload = {
                    "XC_FNC" : "SendSC",
                    "type" : dtype,
                    "data" : data
                }
            elif dtype == 'IR':
                payload = {
                    "XC_FNC" : "Send2",
                    "type" : "CODE",
                    "ir"   : "01",
                    "code" : data
                }

In function setup_discovery() add (I did before if 'blinds' in config:):

    if 'switches' in config:
        for ii in range(0, len(config['switches'])):
            type = config['switches'][ii]['type']

            if 'adr' in config['switches'][ii]:
                adr = config['switches'][ii]['adr']
            elif type == "IT":
                adr = get_IT_address(config['switches'][ii]['on_value'])

            elif type == "IR" and 'name' in config['switches'][ii]:
                adr = get_IR_address(config['switches'][ii]['name'])

            identifier = type + '_' + adr
            host = ''
            mediolaid = 'mediola'
            if isinstance(config['mediola'], list):
                mediolaid = config['buttons'][ii]['mediola']
                for jj in range(0, len(config['mediola'])):
                    if mediolaid == config['mediola'][jj]['id']:
                        host = config['mediola'][jj]['host']
            else:
                host = config['mediola']['host']
            if host == '':
                print('Error: Could not find matching Mediola!')
                continue
            deviceid = "mediola_switches_" + host.replace(".", "")
            dtopic = config['mqtt']['discovery_prefix'] + '/switch/' + \
                     mediolaid + '_' + identifier + '/config'
            topic = config['mqtt']['topic'] + '/switches/' + mediolaid + '/' + identifier
            name = "Mediola Switch"
            if 'name' in config['switches'][ii]:
                name = config['switches'][ii]['name']

            payload = {
              "command_topic" : topic + "/set",
              "payload_on" : "ON",
              "payload_off" : "OFF",
              "optimistic" : True,
              "unique_id" : mediolaid + '_' + identifier,
              "name" : name,
              "device" : {
                "identifiers" : deviceid,
                "manufacturer" : "Mediola",
                "name" : "Mediola Switch",
              },
            }
            # for bidirectional switches, add state channel
            #if config['switches'][ii]['type'] == 'ER':
            #    payload["state_topic"] = topic + "/state"
            payload = json.dumps(payload)
            mqttc.subscribe(topic + "/set")
            mqttc.publish(dtopic, payload=payload, retain=True)

There are referenced two more functions that you have to add to this source too (I did before # Setup MQTT connection):

#calculate switch address from on_value for IT switches
def get_IT_address(on_value):
    # ITT-1500 new self-learning code
    if len(on_value) == 8:
        #26bit address, (2 bit command), 4 bit channel
        return format(int(on_value,16) & 0xFFFFFFC7,"08x")

    # familiy-code, device-code
    elif len(on_value) == 3:
        #familiy-code A-P -> 0-F
        #device-code 01-16 -> 0-F
        family_code = chr(int(on_value[0],16) + 65)
        device_code = format(int(on_value[1],16) + 1,"02")
        return family_code + device_code
    else:
        #print('Error: cannot calculate IT switch address from on_value = ' + on_value)
        return "0"

#calculate switch "address" from name for IR switches
def get_IR_address(name):
    adr = name.lower()
    adr = ''.join(e for e in adr if e.isalnum() and e.isascii())
    return adr

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants