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`:
```bash
$ 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:
```bash
$ git clone git@git.local.awesome-it.de:daniel.morlock/meross-bridge.git
$ cd meross-bridge
$ python setup.py install
# OR:
$ pip install .
$ meross-bridge --help
```
2. Install via pip directly from Gitlab:
```bash
# beware of the / instead of the : in the URL!
$ pip install git+ssh://git@git.local.awesome-it.de/daniel.morlock/meross-bridge.git
# or if you prefer https over ssh
$ pip install git+https://gitlab.awesome-it.de/daniel.morlock/meross-bridge.git
```
Set your Meross credentials in `/etc/default/meross-bridge`:
```bash
$ git clone https://gitlab.awesome-it.de/daniel.morlock/meross-bridge.git ~/path/to/@NAME@
```
Setup a virtualenv using `Python3` and activate it:
MEROSS_EMAIL=yourmail@example.org
MEROSS_PASSWORD=secret
```
```bash
$ 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
(meross-bridge)$
`````
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`:
```bash
(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).
```bash
$ ./runner.py
```
$ 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.
```bash
$ 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:
https://www.openhab.org/blog/2018-12-16-mqtt-arrives-in-the-modern-openhab-2-x-architecture.html.
### 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:
```bash
$ git clone git@git.local.awesome-it.de:daniel.morlock/meross-bridge.git
$ cd meross-bridge
$ python setup.py 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" {
Channels:
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:
```bash
# beware of the / instead of the : in the URL!
$ pip install git+ssh://git@git.local.awesome-it.de/daniel.morlock/meross-bridge.git
# or if you prefer https over ssh
$ pip install git+https://gitlab.awesome-it.de/daniel.morlock/meross-bridge.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 https://community.openhab.org/t/meross-python-library-with-mqtt/83362
import paho.mqtt.client as mqtt
from meross_iot.manager import MerossManager
from meross_iot.meross_event import MerossEventType
from meross_iot.cloud.devices.light_bulbs import GenericBulb
from meross_iot.cloud.devices.power_plugs import GenericPlug
from meross_iot.cloud.devices.door_openers 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.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 %d) 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)
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)
# Register event handlers for the manager...
manager.register_event_handler(event_handler)
# Starts the manager
manager.start()
subscribe_broker(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" % (d.name, channels[i]['devName']))
print(client.subscribe("meross/%s/channel_%i/set" % (d.name, i)))
print(client.subscribe("meross/%s/set" % (d.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()
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