-
Notifications
You must be signed in to change notification settings - Fork 114
Expand file tree
/
Copy pathmain.py
More file actions
executable file
·136 lines (97 loc) · 3.84 KB
/
Copy pathmain.py
File metadata and controls
executable file
·136 lines (97 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python3
"""MiJia GATT to MQTT"""
import re
import time
import paho.mqtt.client as mqtt
from bluepy import btle
MQTT_TOPIC_HUMIDITY = 'home/mijia/humidity'
MQTT_TOPIC_TEMPERATURE = 'home/mijia/temperature'
MQTT_TOPIC_BATTERY = 'home/mijia/battery'
MQTT_TOPIC_STATE = 'home/mijia/status'
MQTT_PUBLISH_DELAY = 60
MQTT_CLIENT_ID = 'mijia'
MQTT_SERVER = 'homeserver'
MQTT_USER = 'mqttuser'
MQTT_PASSWORD = 'mqttpassword'
MIJIA_BTLE_ADDRESS = '4c:65:a8:d7:fb:36'
MIJIA_BATTERY_SERVICE_UUID = btle.UUID('180f')
MIJIA_BATTERY_CHARACTERISTIC_UUID = btle.UUID('2a19')
MIJIA_DATA_SERVICE_UUID = btle.UUID('226c0000-6476-4566-7562-66734470666d')
MIJIA_DATA_CHARACTERISTIC_UUID = btle.UUID('226caa55-6476-4566-7562-66734470666d')
MIJIA_DATA_CHARACTERISTIC_HANDLE = 0x0010
BTLE_SUBSCRIBE_VALUE = bytes([0x01, 0x00])
BTLE_UNSUBSCRIBE_VALUE = bytes([0x00, 0x00])
battery = None
temperature = None
humidity = None
def on_connect(client, userdata, flags, rc):
client.publish(MQTT_TOPIC_STATE, 'connected', 1, True)
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
fetch_sensor_data(bytearray(data).decode('utf-8'))
def main():
mqttc = mqtt.Client(MQTT_CLIENT_ID)
mqttc.username_pw_set(MQTT_USER, MQTT_PASSWORD)
mqttc.will_set(MQTT_TOPIC_STATE, 'disconnected', 1, True)
mqttc.on_connect = on_connect
mqttc.connect(MQTT_SERVER, 1883, 60)
mqttc.loop_start()
last_msg_time = time.time()
while True:
try:
print('Connecting to ' + MIJIA_BTLE_ADDRESS)
dev = btle.Peripheral(MIJIA_BTLE_ADDRESS)
print('Set delegate')
dev.setDelegate(MyDelegate())
# Get battery level
if battery is None:
fetch_battery_level(dev)
print('Battery level: ' + str(battery))
# Subscribe to data characteristic
if temperature is None or humidity is None:
dev.writeCharacteristic(MIJIA_DATA_CHARACTERISTIC_HANDLE, BTLE_SUBSCRIBE_VALUE, True)
while True:
if dev.waitForNotifications(1.0):
print('Temperature: ' + temperature)
print('Humidity: ' + humidity)
dev.writeCharacteristic(MIJIA_DATA_CHARACTERISTIC_HANDLE, BTLE_UNSUBSCRIBE_VALUE, True)
dev.disconnect()
break
except (btle.BTLEDisconnectError, IOError):
print("Disconnected :)")
if battery is not None and temperature is not None and humidity is not None:
delay_gap = time.time() - last_msg_time
if delay_gap < MQTT_PUBLISH_DELAY:
time.sleep(MQTT_PUBLISH_DELAY - delay_gap)
publish_sensor_data(mqttc)
last_msg_time = time.time()
reset_variables()
def reset_variables():
global battery
global temperature
global humidity
battery = None
temperature = None
humidity = None
def fetch_battery_level(dev):
global battery
battery_service = dev.getServiceByUUID(MIJIA_BATTERY_SERVICE_UUID)
battery_characteristic = battery_service.getCharacteristics(MIJIA_BATTERY_CHARACTERISTIC_UUID)[0]
battery = ord(battery_characteristic.read())
def fetch_sensor_data(temp_hum):
global temperature
global humidity
pattern = re.compile('T=([\d.-]+) H=([\d.-]+)')
match = re.match(pattern, temp_hum)
if match:
temperature = match.group(1)
humidity = match.group(2)
def publish_sensor_data(mqttc):
mqttc.publish(MQTT_TOPIC_TEMPERATURE, temperature, 1, True)
mqttc.publish(MQTT_TOPIC_HUMIDITY, humidity, 1, True)
mqttc.publish(MQTT_TOPIC_BATTERY, battery, 1, True)
if __name__ == '__main__':
print('Starting MiJia GATT client')
main()