#!/usr/bin/env python # -*- coding: UTF-8 -*- # vim: expandtab sw=4 ts=4 sts=4: # # Beehive-Monitoring with SMS Alerts and Data-Upload to # Webservice. # # Author: Joerg Lehmann, nbit Informatik GmbH # """Beehive Monitoring""" from __future__ import print_function import gammu.smsd import sys import serial import time import yaml # Read Configuration from YAML-File with open("beielimon-config.yaml", 'r') as stream: try: config_data = yaml.load(stream) except yaml.YAMLError as exc: print(exc) # Constants INVALID_VALUE = -999 # Interface to gammu-smsd smsd = gammu.smsd.SMSD('/etc/gammu-smsdrc') class Scale(object): def __init__(self): self.last_values = [] def __del__(self): pass def AppendReading(self,weigh_in_gram): self.last_values.append(weigh_in_gram) if len(self.last_values) > config_data['number_of_samples']: self.last_values = self.last_values[1:] print('DEBUG WEIGHT: %d' % (weigh_in_gram)) print(self.last_values) def Read(self): pass def SwarmAlarm(self): return (self.GetWeighLoss() > config_data['swarm_alarm_threshold_gram']) def ResetValues(self): self.last_values = [] def GetLastValue(self): return (self.last_values or [0])[-1] def GetWeighLoss(self): last_value = self.GetLastValue() max_value = max(self.last_values or [0]) print('BBB: ',max_value,last_value) return (max_value - last_value) class ScaleUSB_PCE(Scale): def __init__(self,serial_int): Scale.__init__(self) self.ser = serial_int def Read(self): res = INVALID_VALUE self.ser.write('Sx\r\n') weight_string = self.ser.readline() if len(weight_string) == 16: if (weight_string[12:13] == 'g'): try: res = int(weight_string[2:11]) except: print('DEBUG WEIGHT STRING IS NOT AN INTEGER: %s' % (weight_string[2:11])) else: print('DEBUG WEIGHT STRING SHOULD BE IN GRAMS: but is [%s]' % (weight_string[12:13])) else: print('DEBUG WEIGHT STRING SHOULD BE 16 DIGITS: but is %d' % (len(weight_string))) if res != INVALID_VALUE: self.AppendReading(res) class ScaleDummy(Scale): def __init__(self,serial_int): pass def Read(self): pass def send_sms(phonenumbers , text): for phonenumber in phonenumbers: message = { 'Text': text, 'SMSC': {'Location': 1}, 'Number': phonenumber } smsd.InjectSMS([message]) def main(): scales = [] for scale_interface in config_data['scale_interfaces']: if scale_interface == 'usb_pce': ser = serial.Serial(port='/dev/ttyUSB0', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_EVEN, timeout=20000) scale=ScaleUSB_PCE(ser) scales.append(scale) # Main Loop while True: for scale in scales: scale.Read() if scale.SwarmAlarm(): date_time = time.strftime("%d.%m.%Y %H:%M:%S") last_value = scale.GetLastValue() weigh_loss = scale.GetWeighLoss() sms_message = '*** Schwarmalarm ***\nDatum/Zeit: \nLetztes Gewicht [g]: %d\nGewichtsverlust [g]: %d' % (date_time,last_value,weigh_loss) print(config_data['sms_alert_phonenumbers'],sms_message) send_sms(config_data['sms_alert_phonenumbers'],sms_message) scale.ResetValues() time.sleep(config_data['read_scale_interval_sec']) if __name__ == "__main__": main()