meross MSG100 Garagentor Öffner

Eine schwere Geburt!

Vor meiner Zeit mit openHAB wollte ich das Garagentor einfach mit dem Handy aufmachen können, denn für die ganze Familie war nur eine Fernbedienung da und die ist immer dort gelegen, wo man gerade nicht war. Das Handy ist bei allen immer dabei, also hab ich los gelegt.

Leider habe ich damals nicht darauf geachtet, ob man das device z.B. mit tasmota flashen kann, oder ob es eine MQTT Anbindung gibt. Die Entscheidung ist dann auf den meross gefallen, weil der auch einen Sensor hat, der anzeigt, wann das Garagentor ganz offen ist.

Die Montage ist ganz einfach und das Einrichten mit der meross app ist auch kein Problem, solange man einen WLAN Empfang in der Garage hat. Dafür habe ich mir ein devolo Magic 2 WiFi next Starter Kit zugelegt, was auch so einigermaßen funktioniert.

Mit der Einführung von openHAB wollte ich natürlich auch den Zustand des Garagentors sehen und hier ist die Lösung.

Auf meinem Debian Server, auf dem auch der MQTT broker (mosquitto) läuft, installieren wir die meross_iot lib. Anschließend erzeugen wir folgendes python Programm. Ich habe es ins openhab scripts Verzeichnis gespeichert mit dem Namen meross2mqtt.py Die vielen print statements sind nur zum debugging eingebaut

import paho.mqtt.client as mqtt
from meross_iot.manager import MerossManager
from meross_iot.meross_event import MerossEventType
from meross_iot.cloud.devices.door_openers import GenericGarageDoorOpener
from random import randint
import time
import os
import json


EMAIL = "peter@antoni.at"
  // die Zugangsdaten bei meross
PASSWORD = "xxxxxx"
connectMsg = json.dumps({"state":True})

ident = "meross"
client = mqtt.Client(ident)
client.connect("IP des MQTT broker")
client.publish(ident, payload=connectMsg, qos=0, retain=False)
connectMsg = json.dumps({"state":"CLOSED"})
client.publish("meross/Smart Garage Door Opener/state" , payload=connectMsg) 

def on_message(client, userdata, message):
  print("message received ",
         str(message.payload.decode("utf-8")))
  print("message topic=",message.topic)
  print("message qos=",message.qos)
  print("message retain flag=",message.retain)
    
  msg_split = message.topic.split("/")
  if len(msg_split)>2:
    if msg_split[0] == ident and msg_split[-1]=="set":
      handle_message("/".join(msg_split[1:-1]), 
      str(message.payload.decode("utf-8")))
 

client.on_message=on_message
manager = None

def event_handler(eventobj):
  if eventobj.event_type == MerossEventType.DEVICE_ONLINE_STATUS:
    print("Device online status changed: %s went %s" % (eventobj.device.name, eventobj.status))
    client.publish("meross/%s" %(eventobj.device.name),getJsonMsg(eventobj.device)) 
    pass

  elif eventobj.event_type == MerossEventType.DEVICE_SWITCH_STATUS:
    print("Switch state changed: Device %s (channel %s) went %s" % (eventobj.device.name, eventobj.channel_id,
eventobj.switch_state))
    client.publish("meross/%s/channel_%s" %(eventobj.device.name,eventobj.channel_id),getJsonMsg(eventobj.device,eventobj.channel_id))
        
    channel = eventobj.device.get_channels()[eventobj.channel_id]
    if 'devName' in channel:
      client.publish("meross/%s/%s" %(eventobj.device.name,channel['devName']),getJsonMsg(eventobj.device,eventobj.channel_id))                                                                           
  elif eventobj.event_type == MerossEventType.CLIENT_CONNECTION:
    print("MQTT connection state changed: client went %s" % eventobj.status)
    #TODO: Give example of reconnection?

  elif eventobj.event_type == MerossEventType.GARAGE_DOOR_STATUS:
    print("Garage door is now %s" % eventobj.door_state)
    connectMsg = json.dumps({"state":eventobj.door_state.upper()})
    client.publish("meross/%s/state" %(eventobj.device.name),connectMsg) 
        

  else:
    print("Unknown event!")

def initialize_meross():
  global manager
  # Initiates the Meross Cloud Manager. This is in charge of handling the communication with the remote endpoint
  manager = MerossManager(meross_email=EMAIL, meross_password=PASSWORD)
  print("Meross Manager: %s %s" % (EMAIL, PASSWORD))
  # Register event handlers for the manager...
  manager.register_event_handler(event_handler)

  # Starts the manager
  manager.start()
    
  subscribe_broker(manager)
  print("Subscribe Broker: %s" % (manager))
  return manager
    
def subscribe_broker(manager):
  door_openers = manager.get_devices_by_kind(GenericGarageDoorOpener)   
    
  print("All the garage openers I found:")
  for g in door_openers:
    print(g)
    client.subscribe("meross/%s/state" %(g.name))
    
    
def getJsonMsg(d, cNo = None):
  info = {"state":getState(d, cNo), "type": d.type, "friendlyName":d.name, "online": d.online}  
    
  if d.online:
    if cNo is None: 
      info.update(d.get_sys_data())
    else:
      info.update(d.get_channels()[cNo])

  return json.dumps(info)
        
def getState(d, cNo=None):
  status = False
  if d.online:
    if cNo is None:
      status = d.get_status()
    else:
      status = d.get_status(cNo)
    
  if status:
    return "ON"
  return "OFF"
    
    
def getChannelName(d, cNo):
  return d.get_channels()[cNo]['devName']
    
def handle_message(topic, messageStr):
  print("topic %s -> handling message: %s" %(topic, messageStr)) 
  msg = json.loads(messageStr)
  topic_split = topic.split("/")
  device_name = topic_split[0]
    
  if manager is not None:
    device = manager.get_device_by_name(device_name)
      if device is not None:
        if len(topic_split)==1:
          if 'state' in msg:
            if msg['state']=='ON':
              device.turn_on()
            elif msg['state']=='OFF':
              device.turn_off()
         elif len(topic_split)==2:
           channel_name = topic_split[1]
           cNo = -1
           if channel_name.startswith("channel_"):
             cNo = int(channel_name.replace("channel_",""))
           else:
             channels = device.get_channels()
             for i in range(len(channels)):
               if 'devName' in channels[i] and channels[i]['devName']==channel_name:
                 cNo = i
           if cNo>-1:
             if 'state' in msg:
               if msg['state']=='ON':
                 device.turn_on_channel(cNo)
               elif msg['state']=='OFF':
                 device.turn_off_channel(cNo)
           else:
             print("Channel '%s' not found for device '%s'!" %(topic_split[1],device_name))
            
    
if __name__ == '__main__':
    manager = initialize_meross()
    client.loop_forever() 
else:
    client.loop_start() 
    

Damit dieses Programm als service automatisch beim Starten des Computers läuft erzeugen wir folgendes file: /etc/systemd/system/meross2mqtt.service

[Unit]
Description=Meross2MQTT
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /etc/openhab/scripts/meross2mqtt.py

[Install]
WantedBy=multi-user.target

Danach wird das Programm als service eingetragen.
$ sudo systemctl enable meross2mqtt.service
und gestartet
$ sudo systemctl start meross2mqtt.service

Damit können wir jetzt im openHAB eine bridge, thins und item anlegen

Things:
Bridge mqtt:broker:mosquitto "MQTT Broker mosquitto" 
[ host="localhost", port=1883, secure=false, 
  clientID="openHAB" ]
{
Thing topic merossGarageDoorOpener  "Garage Door Opener"  {
Channels:
  Type contact : state "Garage" 
  [stateTopic="meross/Smart Garage Door Opener/state",
   transformationPattern="JSONPATH:$.state"] 
}

Items:
Contact GarageDoorOpener "Garagentor Zustand" 
{channel="mqtt:topic:mosquitto:merossGarageDoorOpener:state"}

Damit kannst du jetzt den Zustand des Garagentors in einer sitemap anzeigen.

Würde mir kein device mehr kaufen, dass ich nicht direkt über MQTT ansprechen kann.

CategoriesSmart Home
  1. Michael says:

    Habe das auch mal probiert, aber anscheinend ist das Skript nicht mehr kompatibel zu den neueren meross-iot Versionen.
    Hast jemand eine neuere Version?

    Michael

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Begin typing your search above and press return to search. Press Esc to cancel.