support for xiaomi aqara thermometer and few other fixes (#18)

* import pip._internal.main to work with pip version > 10

* make auth optional and add support for an optional port

* add worker for xiaomi aqara thermometer

* add support for optional global publishing topic_prefix

* Update config.yaml.example
This commit is contained in:
Marcel Hoppe
2018-08-06 16:05:59 +02:00
committed by zewelor
parent 8d0e4f5a0e
commit 8ea82f14fd
6 changed files with 75 additions and 9 deletions
+1
View File
@@ -1,2 +1,3 @@
config.yaml
__pycache__/
.idea/
+1
View File
@@ -20,6 +20,7 @@ See [Wiki](https://github.com/zewelor/bt-mqtt-gateway/wiki) for more information
* [Linak Desk](https://www.linak.com/business-areas/desks/office-desks/) via [linak_bt_desk](https://github.com/zewelor/linak_bt_desk)
* [MySensors](https://www.mysensors.org/)
* [Xiaomi Mi Flora plant sensor](https://xiaomi-mi.com/sockets-and-sensors/xiaomi-huahuacaocao-flower-care-smart-monitor/) via [miflora](https://github.com/open-homeautomation/miflora)
* Xiaomi Aqara thermometer via [mithermometer](https://github.com/hobbypunk90/mithermometer)
## Getting Started
+8
View File
@@ -1,7 +1,9 @@
mqtt:
host: 192.168.1.1
port: 1883
username: user
password: password
topic_prefix: hostname
manager:
topic_subscription:
@@ -38,3 +40,9 @@ manager:
topic_prefix: miflora
update_interval: 300
mithermometer:
args:
devices:
living_room: 00:11:22:33:44:55
topic_prefix: mithermometer
update_interval: 300
+26 -7
View File
@@ -6,34 +6,53 @@ class MqttClient:
def __init__(self, config):
self._config = config
self._mqttc = mqtt.Client(client_id='bt-mqtt-gateway', clean_session=False)
if self.username is not None and self.password is not None:
self._auth = {'username': self.username, 'password': self.password}
else:
self._auth = None
def publish(self, messages):
if messages is None:
if messages is None or len(messages) == 0:
return
if self.topic_prefix is not None:
for m in messages:
m.topic = "{}/{}".format(self.topic_prefix, m.topic)
publish.multiple(list(map(lambda m: m.as_dict, messages)),
hostname=self.hostname,
auth={'username': self.username, 'password': self.password})
port=self.port,
auth=self._auth)
@property
def hostname(self):
return self._config['host']
@property
def port(self):
return self._config['port'] if 'port' in self._config else 1883
@property
def username(self):
return self._config['username']
return self._config['username'] if 'username' in self._config else None
@property
def password(self):
return self._config['password']
return self._config['password'] if 'password' in self._config else None
@property
def topic_prefix(self):
return self._config['topic_prefix'] if 'topic_prefix' in self._config else None
@property
def mqttc(self):
return self._mqttc
def callbacks_subscription(self, callbacks):
self.mqttc.username_pw_set(self.username, self.password)
self.mqttc.connect(self.hostname)
if self.username is not None and self.password is not None:
self.mqttc.username_pw_set(self.username, self.password)
self.mqttc.connect(self.hostname, port=self.port)
for topic, callback in callbacks:
self.mqttc.message_callback_add(topic, callback)
+37
View File
@@ -0,0 +1,37 @@
from interruptingcow import timeout
from mqtt import MqttMessage
from workers.base import BaseWorker
REQUIREMENTS = ['mithermometer']
monitoredAttrs = ["temperature", "humidity", "battery"]
class MithermometerWorker(BaseWorker):
def _setup(self):
from mithermometer.mithermometer_poller import MiThermometerPoller
from btlewrap.bluepy import BluepyBackend
for name, mac in self.devices.items():
self.devices[name] = MiThermometerPoller(mac, BluepyBackend)
def status_update(self):
ret = []
for name, poller in self.devices.items():
try:
ret += self.update_device_state(name, poller)
except RuntimeError:
pass
return ret
@timeout(8.0)
def update_device_state(self, name, poller):
ret = []
for attr in monitoredAttrs:
ret.append(MqttMessage(topic=self.format_topic(name, attr), payload=poller.parameter_value(attr)))
return ret
+2 -2
View File
@@ -1,7 +1,7 @@
import importlib
import threading
import pip
from pip._internal import main as pip_main
from apscheduler.schedulers.background import BackgroundScheduler
from interruptingcow import timeout
from functools import partial
@@ -95,7 +95,7 @@ class WorkersManager:
@staticmethod
def _pip_install_helper(package_names):
for package in package_names:
pip.main(['install', '-q', package])
pip_main(['install', '-q', package])
def _on_command_wrapper(self, worker_obj, client, _, c):
_LOGGER.debug("on command wrapper for with %s: %s", c.topic, c.payload)