beielipi/bin/process_sms_request.py

284 lines
9.4 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# vim: expandtab sw=4 ts=4 sts=4:
#
# Beehive-Monitoring, process SMS Requests
#
# Author: Joerg Lehmann, nbit Informatik GmbH
#
"""Beehive Monitoring - SMS Processing"""
from __future__ import print_function
import gammu.smsd
import os
import sys
import time
import yaml
import smtplib
import re
import glob
import shutil
from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
# Interface to gammu-smsd
smsd = gammu.smsd.SMSD('/etc/gammu-smsdrc')
# Root Path
APP_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
# Read Configuration from YAML-File
with open("%s/bin/beielimon-config.yaml" % APP_ROOT, 'r') as stream:
try:
config_data = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
def send_sms(phonenumbers , text):
for phonenumber in phonenumbers:
message = {
'Text': text,
'SMSC': {'Location': 1},
'Number': phonenumber
}
#GELD SPAREN smsd.InjectSMS([message])
smsd.InjectSMS([message])
print("Send SMS to %s, Text: %s" % (phonenumber, text))
def send_mail(send_from, send_to, subject, text, files=None):
os.system('/usr/bin/sudo %s/root-bin/connect_to_internet' % (APP_ROOT))
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(text))
for f in files or []:
with open(f, "rb") as fil:
part = MIMEApplication(
fil.read(),
Name=basename(f)
)
# After the file is closed
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)
smtp = smtplib.SMTP(config_data['mailserver'],config_data['mailserver_port'],timeout=60)
smtp.set_debuglevel(1)
smtp.ehlo()
smtp.starttls()
smtp.login(config_data['mailuser'], config_data['mailpwd'])
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()
os.system('/usr/bin/sudo %s/root-bin/disconnect_from_internet' % (APP_ROOT))
def send_help(phonenumber,command):
# SMS Maximale Groesse: 140 Zeichen
if command == '':
sms_message = """Moegliche Befehle:
help, info, balance, reboot, shutdown, hotspot
Naehere Hilfe: help <befehl>, z.B. help info"""
elif command == 'info':
sms_message = """info - letzte Messwerte (SMS)
info 2017 - Messwerte 2017 (EMail)
info 201711 - Messwerte Nov. 2017
info 20171102 - Messwerte 2. Nov. 2017"""
elif command == 'help':
sms_message = "Zeigt die moeglichen Befehle an"
elif command == 'balance':
sms_message = "Anforderung Info zum Prepaid-Guthaben"
elif command == 'reboot':
sms_message = "Neustart des Raspberry Pi's"
elif command == 'shutdown':
sms_message = """Herunterfahren des Raspberry Pi's
ACHTUNG: ZUM STARTEN MUSS STROM AUS- UND WIEDER EINGESTECKT WERDEN!
"""
elif command == 'hotspot':
sms_message = """hotspot on - Hotspot Funktion einschalten
hotspot off - Hotspot ausschalten
Hotspot erlaubt ein Auslesen per Smartphone/Table (WLAN)"""
send_sms([phonenumber],sms_message)
def GetLastValues(scale_uuid):
files = glob.glob("%s/data/weight-%s-????????.log" % (APP_ROOT,scale_uuid))
if len(files) > 0:
with open(sorted(files)[-1], "r") as f:
for line in f: pass
result = line
# Beispiel: 2017-11-07 08:23,0
m = re.match("(\d{4})-(\d{2})-(\d{2}) (\d\d:\d\d),(\d+)", result)
if m:
return "%sg (%s.%s.%s %s)" % (m.group(5),m.group(3),m.group(2),m.group(1),m.group(4))
else:
return "Fehler beim Parsen: %s" % (result)
else:
return "keine Messwerte"
def CreateAttachements(infotime):
mypid = os.getpid()
mycsvdir = "%s/tmp/%s/csv" % (APP_ROOT,mypid)
if not os.path.exists(mycsvdir):
os.makedirs(mycsvdir)
myzipdir = "%s/tmp/%s/zip" % (APP_ROOT,mypid)
if not os.path.exists(myzipdir):
os.makedirs(myzipdir)
res = []
my_pattern = '%s%s' % (infotime,'?' * (8 - len(infotime)))
files = glob.glob("%s/data/weight-*-%s.log" % (APP_ROOT,my_pattern))
for s in config_data['scales']:
filename = "%s/%s-%s.csv" % (mycsvdir,s['alias'].replace(' ','_'),infotime)
with_data = False
with open(filename, 'a') as file:
for ifile in sorted(files):
if (s['scale_uuid'] in ifile) and (infotime in ifile):
with_data = True
with open(ifile, 'r') as ifile:
for line in ifile:
m = re.match("(\d{4})-(\d{2})-(\d{2}) (\d\d:\d\d),(\d+)", line)
if m:
file.write("%s.%s.%s %s,%s\n" % (m.group(3),m.group(2),m.group(1),m.group(4),m.group(5)))
else:
file.write("Fehler beim Parsen: %s" % (line))
if with_data:
res.append(filename)
zipfile = "%s/%s" % (myzipdir,infotime)
shutil.make_archive(zipfile, 'zip', mycsvdir)
return [ "%s.zip" % (zipfile) ]
def send_report(infotime):
# Send EMail Report
my_text = my_text = "Letzte Messwerte:\n"
for s in config_data['scales']:
my_text += "%s: %s\n" % (s['alias'],GetLastValues(s['scale_uuid']))
my_text += "\n\nIm ZIP-File sind die Messwerte der gewuenschten Periode enthalten. Die Daten sind im CSV-Format abgespeichert und koennen z.B. mit Excel analysiert werden.\n"
attachements = CreateAttachements(infotime)
#send_mail(config_data['mailfrom'],config_data['mailto'],'Messwerte BeieliPi',my_text,attachements)
def send_info_sms(phonenumber):
my_text = "Letzte Messwerte:\n"
for s in config_data['scales']:
my_text += "%s: %s\n" % (s['alias'],GetLastValues(s['scale_uuid']))
send_sms([phonenumber],my_text)
def send_info(phonenumber, message_uc):
print("AAA: send_info %s" % message_uc)
m = re.match(".*(INFO)\s+(\d{8})", message_uc)
if m:
send_report(m.group(2))
print("BBB: send_info %s" % message_uc)
else:
m = re.match(".*(INFO)\s+(\d{6})", message_uc)
if m:
send_report(m.group(2))
print("CCC: send_info %s %s" % (message_uc,m.group(2)))
else:
m = re.match(".*(INFO)\s+(\d{4})", message_uc)
if m:
send_report(m.group(2))
print("DDD: send_info %s" % message_uc)
else:
send_info_sms(phonenumber)
print("EEE: send_info %s" % message_uc)
def balance():
send_sms([config_data['balance_number']],config_data['balance_command'])
def reboot():
os.system('/usr/bin/sudo /sbin/init 6')
def shutdown():
os.system('/usr/bin/sudo /sbin/init 0')
def hotspot_on():
os.system('/usr/bin/sudo %s/root-bin/hotspot_on' % (APP_ROOT))
def hotspot_off():
os.system('/usr/bin/sudo %s/root-bin/hotspot_off' % (APP_ROOT))
def command_not_understood(phonenumber, message):
send_sms([phonenumber],'Befehl nicht verstanden: %s\n\nMoegliche Befehle: help, info, balance, reboot, shutdown, hotspot' % (message[:50]))
def main():
print('%s was called at %s with these arguments: %s\n' % (sys.argv[0],formatdate(localtime=True),str(sys.argv)))
if len(sys.argv) != 3:
print("Da kann etwas nicht stimmen, ungueltige Anzahl Argumente")
sys.exit(1)
phonenumber = sys.argv[1]
message = sys.argv[2]
# 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)
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
if not valid_number:
print("Da versucht ein unberechtigter, etwas abzufragen... (Nummer: %s)" % (phonenumber))
sys.exit(2)
if 'HELP INFO' in message_uc:
send_help(phonenumber,'info')
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 '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 __name__ == "__main__":
main()