This commit is contained in:
lolouk44 2020-05-27 23:11:52 +01:00
parent 22dbb9e6d1
commit c47614f196

View file

@ -22,7 +22,9 @@ import binascii
import time import time
import os import os
import sys import sys
import subprocess
from bluepy import btle from bluepy import btle
from bluepy.btle import Scanner, BTLEDisconnectError, BTLEManagementError, DefaultDelegate
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from datetime import datetime from datetime import datetime
@ -38,6 +40,7 @@ MQTT_TIMEOUT = int(os.getenv('MQTT_TIMEOUT', 60))
MQTT_PREFIX = os.getenv('MQTT_PREFIX', 'miscale') MQTT_PREFIX = os.getenv('MQTT_PREFIX', 'miscale')
TIME_INTERVAL = int(os.getenv('TIME_INTERVAL', 30)) TIME_INTERVAL = int(os.getenv('TIME_INTERVAL', 30))
OLD_MEASURE = '' OLD_MEASURE = ''
MQTT_CONNECTED = False
# User Variables... # User Variables...
USER1_GT = int(os.getenv('USER1_GT', '70')) # If the weight is greater than this number, we'll assume that we're weighing User #1 USER1_GT = int(os.getenv('USER1_GT', '70')) # If the weight is greater than this number, we'll assume that we're weighing User #1
@ -65,8 +68,10 @@ class ScanProcessor():
return abs((d2 - d1).days)/365 return abs((d2 - d1).days)/365
def __init__(self): def __init__(self):
global MQTT_CONNECTED
DefaultDelegate.__init__(self)
if not MQTT_CONNECTED:
self.mqtt_client = None self.mqtt_client = None
self.connected = False
self._start_client() self._start_client()
@ -112,19 +117,26 @@ class ScanProcessor():
print ('\t(no data)') print ('\t(no data)')
def _start_client(self): def _start_client(self):
global MQTT_CONNECTED
self.mqtt_client = mqtt.Client() self.mqtt_client = mqtt.Client()
self.mqtt_client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD) self.mqtt_client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
def _on_connect(client, _, flags, return_code): def _on_connect(client, _, flags, return_code):
self.connected = True global MQTT_CONNECTED
MQTT_CONNECTED = True
loop_flag = 0
sys.stdout.write("MQTT connection: %s\n" % mqtt.connack_string(return_code)) sys.stdout.write("MQTT connection: %s\n" % mqtt.connack_string(return_code))
self.mqtt_client.on_connect = _on_connect self.mqtt_client.on_connect = _on_connect
self.mqtt_client.connect(MQTT_HOST, MQTT_PORT, MQTT_TIMEOUT) self.mqtt_client.connect(MQTT_HOST, MQTT_PORT, MQTT_TIMEOUT)
self.mqtt_client.loop_start() self.mqtt_client.loop_start()
while not MQTT_CONNECTED: # wait for MQTT connecting Ack
time.sleep(.01)
def _publish(self, weight, unit, mitdatetime, hasImpedance, miimpedance): def _publish(self, weight, unit, mitdatetime, hasImpedance, miimpedance):
if not self.connected: global MQTT_CONNECTED
if not MQTT_CONNECTED:
sys.stderr.write('Not connected to MQTT server\n') sys.stderr.write('Not connected to MQTT server\n')
exit() exit()
if int(weight) > USER1_GT: if int(weight) > USER1_GT:
@ -151,32 +163,56 @@ class ScanProcessor():
if hasImpedance: if hasImpedance:
lib = Xiaomi_Scale_Body_Metrics.bodyMetrics(weight, height, age, sex, int(miimpedance)) lib = Xiaomi_Scale_Body_Metrics.bodyMetrics(weight, height, age, sex, int(miimpedance))
bodyscale = ['Obese', 'Overweight', 'Thick-set', 'Lack-exerscise', 'Balanced', 'Balanced-muscular', 'Skinny', 'Balanced-skinny', 'Skinny-muscular']
message += ',"Lean Body Mass":"' + "{:.2f}".format(lib.getLBMCoefficient()) + '"' message += ',"Lean Body Mass":"' + "{:.2f}".format(lib.getLBMCoefficient()) + '"'
message += ',"Body Fat":"' + "{:.2f}".format(lib.getFatPercentage()) + '"' message += ',"Body Fat":"' + "{:.2f}".format(lib.getFatPercentage()) + '"'
message += ',"Water":"' + "{:.2f}".format(lib.getWaterPercentage()) + '"' message += ',"Water":"' + "{:.2f}".format(lib.getWaterPercentage()) + '"'
message += ',"Bone Mass":"' + "{:.2f}".format(lib.getBoneMass()) + '"' message += ',"Bone Mass":"' + "{:.2f}".format(lib.getBoneMass()) + '"'
message += ',"Muscle Mass":"' + "{:.2f}".format(lib.getMuscleMass()) + '"' message += ',"Muscle Mass":"' + "{:.2f}".format(lib.getMuscleMass()) + '"'
message += ',"Protein":"' + "{:.2f}".format(lib.getProteinPercentage()) + '"' message += ',"Protein":"' + "{:.2f}".format(lib.getProteinPercentage()) + '"'
#message += ',"Body Type":"' + str(lib.getBodyTypeScale(getBodyType())) + '"' message += ',"Body Type":"' + str(bodyscale[lib.getBodyType()]) + '"'
#message += ',"Metabolic Age":"' + str(lib.getMetabolicAge()) + '"' message += ',"Metabolic Age":"' + "{:.0f}".format(lib.getMetabolicAge()) + '"'
message += ',"TimeStamp":"' + mitdatetime + '"' message += ',"TimeStamp":"' + mitdatetime + '"'
message += '}' message += '}'
try:
self.mqtt_client.publish(MQTT_PREFIX + '/' + user + '/weight', message, qos=1, retain=True) self.mqtt_client.publish(MQTT_PREFIX + '/' + user + '/weight', message, qos=1, retain=True)
sys.stdout.write('Sent data to topic %s: %s' % (MQTT_PREFIX + '/' + user + '/weight', message + '\n')) sys.stdout.write('Sent data to topic %s: %s' % (MQTT_PREFIX + '/' + user + '/weight', message + '\n'))
except:
sys.stdout.write('Could not publish to MQTT, Disconnecting...\n')
MQTT_CONNECTED = False
self.mqtt_client.disconnect()
pass
def main(): def main():
sys.stdout.write(' \n') sys.stdout.write(' \n')
sys.stdout.write('-------------------------------------\n') sys.stdout.write('-------------------------------------\n')
sys.stdout.write('Starting Xiaomi mi Scale...\n') sys.stdout.write('Starting Xiaomi mi Scale...\n')
scanner = btle.Scanner().withDelegate(ScanProcessor()) BluetoothFailCounter = 0
while True: while True:
try: try:
scanner.scan(5, passive=True) # Adding passive=True to try and fix issues on RPi devices scanner = btle.Scanner().withDelegate(ScanProcessor())
except: scanner.scan(5) # Adding passive=True to try and fix issues on RPi devices
sys.stderr.write("Error while running the script, continuing. If you see this message too often/constantly there is probably a real issue...\n") except BTLEDisconnectError as error:
sys.stderr.write(f"btle disconnected: {error}\n")
pass pass
except BTLEManagementError as error:
sys.stderr.write(f"Bluetooth connection error: {error}\n")
if BluetoothFailCounter >= 4:
sys.stderr.write(f"5+ Bluetooth connection errors. Resetting Bluetooth...\n")
cmd = 'hciconfig hci0 reset'
ps = subprocess.Popen(cmd, shell=True)
time.sleep(30)
BluetoothFailCounter = 0
else:
BluetoothFailCounter+=1
pass
except:
sys.stderr.write("Error while running the script, continuing...\n")
pass
else:
BluetoothFailCounter = 0
time.sleep(TIME_INTERVAL) time.sleep(TIME_INTERVAL)
if __name__ == "__main__": if __name__ == "__main__":