bluetooth scale by nbit informatik
This commit is contained in:
@@ -20,8 +20,6 @@ mailfrom: info@nbit.ch
|
||||
mailto: joerg.lehmann@nbit.ch
|
||||
mailuser: nbitinf@nbit.ch
|
||||
mailpwd: ukihefak27
|
||||
balance_number: "444"
|
||||
balance_command: "STATUS"
|
||||
forward_sms_from_this_number: "444"
|
||||
balance_ussd: "*121#"
|
||||
master_sms_number: "+41765006123"
|
||||
manipulation_duration_minutes: 60
|
||||
|
||||
@@ -19,6 +19,8 @@ import random
|
||||
import string
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import datetime
|
||||
|
||||
# Root Path
|
||||
APP_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
@@ -58,6 +60,9 @@ class Scale(object):
|
||||
def __init__(self, scale_config):
|
||||
self.last_values = []
|
||||
self.scale_config = scale_config
|
||||
self.accu = INVALID_VALUE
|
||||
self.hum = INVALID_VALUE
|
||||
self.temp = INVALID_VALUE
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
@@ -76,6 +81,26 @@ class Scale(object):
|
||||
with open(datafilename, 'a') as file:
|
||||
file.write('%s,%d\n' % (timestamp,weigh_in_gram))
|
||||
|
||||
if self.accu != INVALID_VALUE and not(swarm_alarm):
|
||||
prefix = 'accu'
|
||||
datafilename = "%s/data/%s-%s-%s%s%s.log" % (APP_ROOT,prefix,self.scale_config['scale_uuid'],year,month,day)
|
||||
with open(datafilename, 'a') as file:
|
||||
file.write('%s,%.1f\n' % (timestamp,self.accu / 100.0))
|
||||
|
||||
if self.hum != INVALID_VALUE and not(swarm_alarm):
|
||||
prefix = 'humidity'
|
||||
datafilename = "%s/data/%s-%s-%s%s%s.log" % (APP_ROOT,prefix,self.scale_config['scale_uuid'],year,month,day)
|
||||
with open(datafilename, 'a') as file:
|
||||
file.write('%s,%d\n' % (timestamp,self.hum / 10))
|
||||
|
||||
if self.temp != INVALID_VALUE and not(swarm_alarm):
|
||||
prefix = 'temp'
|
||||
datafilename = "%s/data/%s-%s-%s%s%s.log" % (APP_ROOT,prefix,self.scale_config['scale_uuid'],year,month,day)
|
||||
with open(datafilename, 'a') as file:
|
||||
file.write('%s,%d\n' % (timestamp,self.temp / 10))
|
||||
|
||||
|
||||
|
||||
def AppendReading(self,weigh_in_gram):
|
||||
self.last_values.append(weigh_in_gram)
|
||||
if len(self.last_values) > config_data['number_of_samples']:
|
||||
@@ -129,6 +154,41 @@ class ScaleUSB_PCE(Scale):
|
||||
if res != INVALID_VALUE:
|
||||
self.AppendReading(res)
|
||||
|
||||
class ScaleBT(Scale):
|
||||
def __init__(self,scale_config):
|
||||
Scale.__init__(self, scale_config)
|
||||
|
||||
def Read(self):
|
||||
res = INVALID_VALUE
|
||||
|
||||
filename = "/home/beieli/bt-readings/%s.json" % (self.scale_config['mac'])
|
||||
try:
|
||||
data = json.load(open(filename))
|
||||
except:
|
||||
return
|
||||
|
||||
# Wenn die Daten aelter als 15 Minuten sind loeschen wir das File
|
||||
delta_in_seconds = (datetime.datetime.now() - datetime.datetime.strptime(data['datetime'],'%d.%m.%Y %H:%M')).total_seconds()
|
||||
print(delta_in_seconds)
|
||||
if ( delta_in_seconds > 15*60):
|
||||
print('DEBUG [%s,%s]' % (datetime.datetime.now(),data['datetime']))
|
||||
print('Readings are older than 15 minutes, removing them [%s]' % (self.scale_config['mac']))
|
||||
os.remove(filename)
|
||||
else:
|
||||
res = ((data['w1'] - self.scale_config['offset1']) / self.scale_config['ratio1']) + ((data['w2'] - self.scale_config['offset2']) / self.scale_config['ratio2'])
|
||||
if res < 0:
|
||||
print('DEBUG: Read Bluetooth Scale; Value less than 0, set it to 0: %d' % (res))
|
||||
res = 0
|
||||
|
||||
self.accu = data['accu']
|
||||
self.hum = data['hum']
|
||||
self.temp = data['temp']
|
||||
|
||||
print('DEBUG: Read Bluetooth Scale: %d' % (res))
|
||||
|
||||
if res != INVALID_VALUE:
|
||||
self.AppendReading(res)
|
||||
|
||||
|
||||
class ScaleDummy(Scale):
|
||||
def __init__(self,scale_config):
|
||||
@@ -153,6 +213,8 @@ class ScaleDummy(Scale):
|
||||
if (last_value + delta < 0):
|
||||
delta = random.randint(0,4)
|
||||
|
||||
|
||||
print('DEBUG: Read Dummy Scale: %d' % (last_value + delta))
|
||||
self.AppendReading(last_value + delta)
|
||||
|
||||
|
||||
@@ -177,6 +239,9 @@ def main():
|
||||
timeout=20)
|
||||
scale=ScaleUSB_PCE(ser, scale_config)
|
||||
scales.append(scale)
|
||||
elif scale_config['interface_type'] == 'btscale':
|
||||
scale=ScaleBT(scale_config)
|
||||
scales.append(scale)
|
||||
elif scale_config['interface_type'] == 'dummy':
|
||||
scale=ScaleDummy(scale_config)
|
||||
scales.append(scale)
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
# vim: expandtab sw=4 ts=4 sts=4:
|
||||
#
|
||||
# Bluetooth Scale Monitor
|
||||
#
|
||||
# Author: Joerg Lehmann, nbit Informatik GmbH
|
||||
#
|
||||
"""Bluetooth Scale Monitor"""
|
||||
|
||||
import json
|
||||
import datetime
|
||||
from bluepy.btle import Scanner, DefaultDelegate
|
||||
|
||||
LONG = 2147483648L
|
||||
INT = 32768
|
||||
|
||||
class ScanDelegate(DefaultDelegate):
|
||||
def __init__(self):
|
||||
DefaultDelegate.__init__(self)
|
||||
|
||||
def ProcessReading(self, mac, value):
|
||||
data = {}
|
||||
data['datetime'] = datetime.datetime.now().strftime("%d.%m.%Y %H:%M")
|
||||
data['w1'] = long(value[0:8],16) - LONG
|
||||
data['w2'] = long(value[8:16],16) - LONG
|
||||
data['temp'] = int(value[16:20],16) - INT
|
||||
data['hum'] = int(value[20:24],16)
|
||||
data['accu'] = int(value[24:28],16)
|
||||
|
||||
filename = "/home/beieli/bt-readings/%s.json" % (mac)
|
||||
with open(filename,'w') as outfile:
|
||||
json.dump(data, outfile, indent=4, sort_keys=True)
|
||||
|
||||
def handleDiscovery(self, dev, isNewDev, isNewData):
|
||||
if isNewData:
|
||||
for (adtype, desc, value) in dev.getScanData():
|
||||
if desc == 'Manufacturer' and value.startswith('1234' ):
|
||||
self.ProcessReading(dev.addr, value[4:])
|
||||
|
||||
scanner = Scanner().withDelegate(ScanDelegate())
|
||||
while True:
|
||||
scanner.scan(5)
|
||||
+48
-50
@@ -20,6 +20,7 @@ import glob
|
||||
import shutil
|
||||
import random
|
||||
import string
|
||||
import subprocess
|
||||
from os.path import basename
|
||||
from email.mime.application import MIMEApplication
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
@@ -273,8 +274,11 @@ def is_muted():
|
||||
|
||||
return res
|
||||
|
||||
def balance():
|
||||
send_sms([config_data['balance_number']],config_data['balance_command'])
|
||||
def balance(phonenumber):
|
||||
sm.Terminate()
|
||||
sms_message = subprocess.check_output(["/usr/bin/sudo","/home/beieli/root-bin/get_balance.sh", config_data['balance_ussd']])
|
||||
sm.Init()
|
||||
send_sms([phonenumber],sms_message)
|
||||
|
||||
def reboot():
|
||||
os.system('/usr/bin/sudo /sbin/init 6')
|
||||
@@ -293,57 +297,51 @@ def command_not_understood(phonenumber, message):
|
||||
|
||||
|
||||
def process_received_sms(phonenumber,message):
|
||||
# Falls es von forward_sms_from_this_number kommt, machen wir ein Foward an
|
||||
# die Master Nummer
|
||||
if phonenumber == config_data['forward_sms_from_this_number']:
|
||||
send_sms([config_data['master_sms_number']],message)
|
||||
# message in Grossbuchstaben (damit Gross-/Kleinschreibung keine Rolle spielt)
|
||||
message_uc = message.upper()
|
||||
|
||||
else:
|
||||
# message in Grossbuchstaben (damit Gross-/Kleinschreibung keine Rolle spielt)
|
||||
message_uc = message.upper()
|
||||
|
||||
# Bestimmung, ob es eine gueltige Telefonnummer ist
|
||||
valid_number = False
|
||||
for s in config_data['scales']:
|
||||
if phonenumber in s['sms_alert_phonenumbers']:
|
||||
valid_number = True
|
||||
# Bestimmung, ob es eine gueltige Telefonnummer ist
|
||||
valid_number = False
|
||||
for s in config_data['scales']:
|
||||
if phonenumber in s['sms_alert_phonenumbers']:
|
||||
valid_number = True
|
||||
|
||||
if not valid_number:
|
||||
print("Da versucht ein unberechtigter, etwas abzufragen... (Nummer: %s)" % (phonenumber))
|
||||
return
|
||||
if not valid_number:
|
||||
print("Da versucht ein unberechtigter, etwas abzufragen... (Nummer: %s)" % (phonenumber))
|
||||
return
|
||||
|
||||
if 'HELP INFO' in message_uc:
|
||||
send_help(phonenumber,'info')
|
||||
elif 'HELP MANIPULATION' in message_uc:
|
||||
send_help(phonenumber,'manipulation')
|
||||
elif 'HELP HELP' in message_uc:
|
||||
send_help(phonenumber,'help')
|
||||
elif 'HELP BALANCE' in message_uc:
|
||||
send_help(phonenumber,'balance')
|
||||
elif 'HELP REBOOT' in message_uc:
|
||||
send_help(phonenumber,'reboot')
|
||||
elif 'HELP SHUTDOWN' in message_uc:
|
||||
send_help(phonenumber,'shutdown')
|
||||
elif 'HELP HOTSPOT' in message_uc:
|
||||
send_help(phonenumber,'hotspot')
|
||||
elif 'HELP' in message_uc:
|
||||
send_help(phonenumber,'')
|
||||
elif 'INFO' in message_uc:
|
||||
send_info(phonenumber, message_uc)
|
||||
elif 'MANIPULATION' in message_uc:
|
||||
start_manipulation()
|
||||
elif 'BALANCE' in message_uc:
|
||||
balance()
|
||||
elif 'REBOOT' in message_uc:
|
||||
reboot()
|
||||
elif 'SHUTDOWN' in message_uc:
|
||||
shutdown()
|
||||
elif 'HOTSPOT OFF' in message_uc:
|
||||
hotspot_off()
|
||||
elif 'HOTSPOT ON' in message_uc:
|
||||
hotspot_on()
|
||||
else:
|
||||
command_not_understood(phonenumber, message)
|
||||
if 'HELP INFO' in message_uc:
|
||||
send_help(phonenumber,'info')
|
||||
elif 'HELP MANIPULATION' in message_uc:
|
||||
send_help(phonenumber,'manipulation')
|
||||
elif 'HELP HELP' in message_uc:
|
||||
send_help(phonenumber,'help')
|
||||
elif 'HELP BALANCE' in message_uc:
|
||||
send_help(phonenumber,'balance')
|
||||
elif 'HELP REBOOT' in message_uc:
|
||||
send_help(phonenumber,'reboot')
|
||||
elif 'HELP SHUTDOWN' in message_uc:
|
||||
send_help(phonenumber,'shutdown')
|
||||
elif 'HELP HOTSPOT' in message_uc:
|
||||
send_help(phonenumber,'hotspot')
|
||||
elif 'HELP' in message_uc:
|
||||
send_help(phonenumber,'')
|
||||
elif 'INFO' in message_uc:
|
||||
send_info(phonenumber, message_uc)
|
||||
elif 'MANIPULATION' in message_uc:
|
||||
start_manipulation()
|
||||
elif 'BALANCE' in message_uc:
|
||||
balance(phonenumber)
|
||||
elif 'REBOOT' in message_uc:
|
||||
reboot()
|
||||
elif 'SHUTDOWN' in message_uc:
|
||||
shutdown()
|
||||
elif 'HOTSPOT OFF' in message_uc:
|
||||
hotspot_off()
|
||||
elif 'HOTSPOT ON' in message_uc:
|
||||
hotspot_on()
|
||||
else:
|
||||
command_not_understood(phonenumber, message)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
Reference in New Issue
Block a user