initial version

This commit is contained in:
lolouk44 2018-11-29 16:31:22 +00:00 committed by GitHub
parent 970fe061b3
commit d3980ab3b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

138
Xiaomi_Scale.py Normal file
View file

@ -0,0 +1,138 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
import argparse
import binascii
import time
import os
import sys
from bluepy import btle
import paho.mqtt.client as mqtt
from datetime import datetime
MISCALE_MAC = 'REDACTED'
MQTT_USERNAME = 'REDACTED'
MQTT_PASSWORD = 'REDACTED'
MQTT_HOST = 'REDACTED'
MQTT_PORT = 1883
MQTT_TIMEOUT = 60
if os.getenv('C', '1') == '0':
ANSI_RED = ''
ANSI_GREEN = ''
ANSI_YELLOW = ''
ANSI_CYAN = ''
ANSI_WHITE = ''
ANSI_OFF = ''
else:
ANSI_CSI = "\033["
ANSI_RED = ANSI_CSI + '31m'
ANSI_GREEN = ANSI_CSI + '32m'
ANSI_YELLOW = ANSI_CSI + '33m'
ANSI_CYAN = ANSI_CSI + '36m'
ANSI_WHITE = ANSI_CSI + '37m'
ANSI_OFF = ANSI_CSI + '0m'
class ScanProcessor():
def __init__(self):
self.mqtt_client = None
self.connected = False
self._start_client()
def handleDiscovery(self, dev, isNewDev, isNewData):
if dev.addr == MISCALE_MAC.lower() and isNewDev:
# print (' Device: %s (%s), %d dBm %s. ' %
# (
# ANSI_WHITE + dev.addr + ANSI_OFF,
# dev.addrType,
# dev.rssi,
# ('' if dev.connectable else '(not connectable)'))
# , end='')
for (sdid, desc, data) in dev.getScanData():
### Xiaomi V1 Scale ###
if data.startswith('1d18') and sdid == 22:
measunit = data[4:6]
measured = int((data[8:10] + data[6:8]), 16) * 0.01
unit = ''
if measunit.startswith(('03', 'b3')): unit = 'lbs'
if measunit.startswith(('12', 'b2')): unit = 'jin'
if measunit.startswith(('22', 'a2')): unit = 'kg' ; measured = measured / 2
if unit:
print('')
self._publish(round(measured, 2, "", ""), unit)
else:
print("Scale is sleeping.")
### Xiaomi V2 Scale ###
if data.startswith('1b18') and sdid == 22:
measunit = data[4:6]
measured = int((data[28:30] + data[26:28]), 16) * 0.01
unit = ''
if measunit == "03": unit = 'lbs'
if measunit == "02": unit = 'kg' ; measured = measured / 2
mitdatetime = datetime.strptime(str(int((data[10:12] + data[8:10]), 16)) + " " + str(int((data[12:14]), 16)) +" "+ str(int((data[14:16]), 16)) +" "+ str(int((data[16:18]), 16)) +" "+ str(int((data[18:20]), 16)) +" "+ str(int((data[20:22]), 16)), "%Y %m %d %H %M %S")
miimpedance = str(int((data[24:26] + data[22:24]), 16))
if unit:
print('')
self._publish(round(measured, 2), unit, str(mitdatetime), miimpedance)
else:
print("Scale is sleeping.")
if not dev.scanData:
print ('\t(no data)')
print
def _start_client(self):
self.mqtt_client = mqtt.Client()
self.mqtt_client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
def _on_connect(client, _, flags, return_code):
self.connected = True
#print("MQTT connection returned result: %s" % mqtt.connack_string(return_code))
self.mqtt_client.on_connect = _on_connect
self.mqtt_client.connect(MQTT_HOST, MQTT_PORT, MQTT_TIMEOUT)
self.mqtt_client.loop_start()
def _publish(self, weight, unit, mitdatetime, miimpedance):
if not self.connected:
raise Exception('not connected to MQTT server')
if int(weight) > 72:
user="lolo"
elif int(weight) < 50:
user="kiaan"
else:
user = "div"
prefix = '{}/{}'.format(user+'/weight', unit)
self.mqtt_client.publish(prefix, weight, qos=1, retain=True)
print('\tSent data to topic %s: %s %s' % (prefix, weight, unit))
if miimpedance:
prefix = '{}/{}'.format(user+'/weight', "Timestamp")
self.mqtt_client.publish(prefix, mitdatetime, qos=1, retain=True)
if int(miimpedance) < 6000: #scale sends fffd (65533) if impedance could not be measured
prefix = '{}/{}'.format(user+'/weight', "Impedance")
self.mqtt_client.publish(prefix, miimpedance, qos=1, retain=True)
def main():
# while(True):
scanner = btle.Scanner().withDelegate(ScanProcessor())
# print (ANSI_RED + "Scanning for devices..." + ANSI_OFF)
devices = scanner.scan(5)
# time.sleep(300)
# devices = scanner.scan(5)
if __name__ == "__main__":
main()