Commit 3c3c3a07 authored by Daniel Morlock's avatar Daniel Morlock
Browse files

Add some docs, remove unused code.

parent 652990cd
# Meross Bridge
## Usage
## Installation
Check the help section of `meross-bridge`:
$ meross-bridge --help
For production usage you can just install the package like any other python package. There are two ways to do this:
## Setup
### For development usage
1. Checkout by hand and install by hand or via pip:
Get the source code:
$ git clone
$ cd meross-bridge
$ python install
# OR:
$ pip install .
$ meross-bridge --help
2. Install via pip directly from Gitlab:
# beware of the / instead of the : in the URL!
$ pip install git+ssh://
# or if you prefer https over ssh
$ pip install git+
Set your Meross credentials in `/etc/default/meross-bridge`:
$ git clone ~/path/to/@NAME@
Setup a virtualenv using `Python3` and activate it:
$ virtualenv -p python3 ~/.virtualenvs/meross-bridge
$ source ~/.virtualenvs/meross-bridge/bin/activate
# alternatively install it in your project directory
$ cd ~/path/to/meross-bridge
$ virtualenv -p python3 env3
$ source env3/bin/activate
You might want to change mode to `0600` since you store a password in this file:
$ chmod 0600 /etc/default/meross-bridge
Install requirements:
To start on system boot, you can use the `meross-bridge.service` file for `systemd`:
(meross-bridge)$ pip install -r requirements.txt
$ sudo cp systemd/meross-bridge.service /etc/systemd/system/meross-bridge.service
$ sudo systemctl enable meross-bridge.service
$ sudo systemctl start meross-bridge.service
#### Usage while developing
There are two ways you can invoke `meross-bridge` while developing (i.e. while in your virtualenv).
Check the logs as follows:
1. There is a wrapper that can be used to run it from your PATH. This is only intended for quick usage while development,
not as a binary (i.e. don't link to it or anything; have a look at the next topic).
$ ./
$ sudo journalctl -fu meross-bridge.service
2. The second way is via pip. Pip can install a python package in edit-mode. If you do this all code changes will
immediately take effect. To skip the virtualenv, you can append "--user" to pip in order to install `meross-bridge` using the user scheme.
$ cd ~/path/to/meross-bridge
$ pip install [--user] -e .
$ meross-bridge
# make changes
$ meross-bridge
# new behaviour, changes take effect immediately.
## OpenHAB
### For production usage
### MQTT Broker
You need to run a MQTT broker i.e. the embedded broker from OpenHAB:
1. To do so, go to the Paper UI
2. Select "Add-ons"
3. Switch to "Misc"-Tab
4. Install "MQTT Broker Moquette" (misc-mqttbroker - 2.5.4) or "MQTT Embedded Broker"
Note that there is some mess in the current OpenHAB docs and forums where Moquette was replaced with Embedded Broker:
### MQTT Binding
Further we need to install a MQTT binding to connect to the broker:
1. To do so, go to the Paper UI
2. Select "Add-ons"
3. Switch to "Bindings"-Tab
4. Install "MQTT Binding" (binding-mqtt - 2.5.4)
### Things
Example to create the thing `meross_thermostats_device_1` for a Meross thermostat with the appropriate channels:
For production usage you can just install the package like any other python package. There are two ways to do this:
1. Checkout by hand and install by hand or via pip:
$ git clone
$ cd meross-bridge
$ python install
# OR:
$ pip install .
$ meross-bridge --help
Bridge mqtt:broker:broker "MQTT Broker" [ host="localhost", port=1883, secure=false, clientID="meross-bridge-client" ]
Thing topic meross_thermostats_device_1 "Meross Thermostat: Device 1" {
Type string : name "name" [ stateTopic="meross/<device_id>/name"]
Type string : mode "mode" [ stateTopic="meross/<device_id>/mode", commandTopic="meross/<device_id>/set/mode"]
Type number : mode "mode_value" [ stateTopic="meross/<device_id>/mode_value", commandTopic="meross/<device_id>/set/mode_value"]
Type switch : onff "onoff" [ stateTopic="meross/<device_id>/onoff", on="True", off="False", commandTopic="meross/<device_id>/set/onoff"]
Type switch : heating "heating" [ stateTopic="meross/<device_id>/heating", on="True", off="False"]
Type switch : online "online" [ stateTopic="meross/<device_id>/online", on="True", off="False"]
Type number : battery "battery" [ stateTopic="meross/<device_id>/battery"]
Type number : room "room" [ stateTopic="meross/<device_id>/room_temperature"]
Type number : target "target" [ stateTopic="meross/<device_id>/target_temperature", commandTopic="meross/<device_id>/set/target_temperature"]
2. Install via pip directly from gitlab:
# beware of the / instead of the : in the URL!
$ pip install git+ssh://
# or if you prefer https over ssh
$ pip install git+
You'll find the appropriate `<device_id>` in the logging output from device discovery after starting the `meross-bridge`.
### Items
Example to create things from the thing `meross_thermostats_device_1` from above:
String meross_thermostats_device_1_name "meross_thermostats_device_1_name" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:name"}
String meross_thermostats_device_1_mode "meross_thermostats_device_1_mode" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:mode"}
Number meross_thermostats_device_1_mode_value "meross_thermostats_device_1_mode_value" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:mode_value"}
Switch meross_thermostats_device_1_onoff "meross_thermostats_device_1_onoff" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:onff"}
Switch meross_thermostats_device_1_heating "meross_thermostats_device_1_heating" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:heating"}
Switch meross_thermostats_device_1_online "meross_thermostats_device_1_online" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:online"}
Number meross_thermostats_device_1_battery "meross_thermostats_device_1_battery" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:battery"}
Number meross_thermostats_device_1_room "meross_thermostats_device_1_room" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:room"}
Number meross_thermostats_device_1_target "meross_thermostats_device_1_target" (meross) {channel="mqtt:topic:broker:meross_thermostats_device_1:target"}
\ No newline at end of file
# See
import paho.mqtt.client as mqtt
from meross_iot.manager import MerossManager
from meross_iot.meross_event import MerossEventType
from import GenericBulb
from import GenericPlug
from import GenericGarageDoorOpener
from random import randint
import time
import os
import json
EMAIL = "<your email used for registration with meross>"
PASSWORD = "<your password used for registration with meross>"
connectMsg = json.dumps({"state": True})
ident = "meross"
client = mqtt.Client(ident)
client.connect("<ip address of openhab server>")
client.publish(ident, payload=connectMsg, qos=0, retain=False)
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.status))
client.publish("meross/%s" % (, getJsonMsg(eventobj.device))
elif eventobj.event_type == MerossEventType.DEVICE_SWITCH_STATUS:
print("Switch state changed: Device %s (channel %d) went %s" % (, eventobj.channel_id,
client.publish("meross/%s/channel_%s" % (, 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" % (, 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)
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)
# Register event handlers for the manager...
# Starts the manager
return manager
def subscribe_broker(manager):
# print("All the supported devices I found:")
all_devices = manager.get_supported_devices()
for d in all_devices:
if hasattr(d, 'get_channels'):
channels = d.get_channels()
for i in range(len(channels)):
if 'devName' in channels[i]:
client.subscribe("meross/%s/%s/set" % (, channels[i]['devName']))
print(client.subscribe("meross/%s/channel_%i/set" % (, i)))
print(client.subscribe("meross/%s/set" % (
def getJsonMsg(d, cNo=None):
info = {"state": getState(d, cNo), "type": d.type, "friendlyName":, "online":}
if cNo is None:
return json.dumps(info)
def getState(d, cNo=None):
status = False
if cNo is None:
status = d.get_status()
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':
elif msg['state'] == 'OFF':
elif len(topic_split) == 2:
channel_name = topic_split[1]
cNo = -1
if channel_name.startswith("channel_"):
cNo = int(channel_name.replace("channel_", ""))
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':
elif msg['state'] == 'OFF':
print("Channel '%s' not found for device '%s'!" % (topic_split[1], device_name))
if __name__ == '__main__':
manager = initialize_meross()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment