from blinker import signal from blinker import Signal import json import gv import time from datetime import timedelta import os import sys # MQTT import paho.mqtt.publish as publish from mqtt import get_mqtt_options def publish_mqtt(notify): datamq=get_mqtt_options() #load data from file try: with open('./data/mqtt.json', 'r') as f: # Read the settings from file file_data = json.load(f) for key, value in file_data.iteritems(): if key in datamq: datamq[key] = value except Exception as err: print "couldn't get option values :" + str(err) pass # if this event has been configured to send an MQTT message if datamq[notify] != "off": # get the topic and body topic1 = notify + 'topic' topic = datamq[topic1] body1 = notify + 'msg' temp = datamq[body1] # If temp = 'file' then the body will be read from mqtxxfile.json if temp == 'file': try: file_msg = '' filename = './data/' +notify + 'file.dat' with open(filename, 'r') as g: # Read the settings from file file_msg = g.read() temp = file_msg except Exception as err: print "couldn't get message payload :" + str(err) pass # We now have a comma separated list of gv variables to place in the payload # We will eval each of this list if they are a valid gv variable # otherwise they will be placed in the payload as-is # First get the list of variables in gv s = [] # < indicates this item is a function s += [item for item in dir(gv) if (not item.startswith("_")) or (not item.startswith("<"))] s1 = [] for i in s: x1 = "gv." + i s1.append(x1) # # at this stage s1 contains a list of variable names that are in gv # split the comma separated list of variables that are in temp vars = temp.split(",") # Build the payload - add eval of the variable if it is in s1 # it would be possible to add other special variables eg cpu temp, runtime since reboot etc payload = "" for i in vars: # get rid of white space if it is not a simple string i2 = str(i) i1 = i2.strip() # add a comma separator if it is not the first if payload != "": payload += " , " # Watch out for special variables # eg Time will be time.asctime(time.localtime(gv.now)) if i1 == "Time": payload += time.asctime(time.gmtime(gv.now)) elif i1 == "CPUtemp": payload += getCPUtemperature() elif i1 == "CPUusage": payload += getCPUuse() elif i1 == "RAMtotal": RAM_stats = getRAMinfo() payload += str(round(int(RAM_stats[0]) /1000,1)) elif i1 == "RAMused": RAM_stats = getRAMinfo() payload += str(round(int(RAM_stats[1]) /1000,1)) elif i1 == "RAMfree": RAM_stats = getRAMinfo() payload += str(round(int(RAM_stats[2]) /1000,1)) elif i1 == "Getlogin": payload += os.getlogin() elif i1 == "Uptime": with open('/proc/uptime','r') as f5: uptime_seconds = float(f5.readline().split()[0]) uptime_string = str(timedelta(seconds = uptime_seconds)) payload += uptime_string elif i1 in s1: # if it is a string then add it to the message, # if it is the name of a variable, evaluate it first j = "" j=str(i1) k = eval(j) payload += str(k) else: payload = payload + i payload1 = str(payload) if datamq['mqthost'] != '' and datamq['mqtport'] != '' : mqtt_host = datamq['mqthost'] # MQTT Broker Host name/IP mqtt_port = datamq['mqtport'] # MQTT Broker port if datamq['mqtqos'] == '2' : mqtqos = 2 elif datamq['mqtqos'] == '1' : mqtqos = 1 else: mqtqos = 0 if datamq['mqtretain'] == 'True' : mqtretain = True else: mqtretain = False try: publish.single(topic, payload1,hostname=mqtt_host,port=int(mqtt_port),retain=mqtretain,qos=mqtqos) except Exception as err: print "Couldn't publish :" + str(err) pass else: pass return ### valves ### def notify_zone_change(name, **kw): # There has been a change in the zone ie some stations have gone on/off # For this information to be useful, anyone receiving this message would want to # know the name of the station, whether it was a master valve, and whether it just turned on or off # It may be necessary to know the time unless the receiver of this message can time stamp # the message. As we use the Retain = true feature of MQTT this may not be the case. # So we should send gv.now, gv.snames, gv.sn and gv.now # I am not sure that this notification is coming when a station turns on or when it is scheduled to turn on publish_mqtt("mqtzc") zones = signal('zone_change') zones.connect(notify_zone_change) ### login ### def notify_login(name, **kw): # As they only enter the password,we don't know who they are publish_mqtt("mqtlg") loggedin = signal('loggedin') loggedin.connect(notify_login) ### System settings ### def notify_value_change(name, **kw): # System settings # publish_mqtt("mqtcc") value_change = signal('value_change') value_change.connect(notify_value_change) ### Option settings ### def notify_option_change(name, **kw): publish_mqtt("mqtoc") option_change = signal('option_change') option_change.connect(notify_option_change) ### Reboot ### def notify_rebooted(name, **kw): publish_mqtt("mqtrb") rebooted = signal('rebooted') rebooted.connect(notify_rebooted) ### station names ### def notify_station_names(name, **kw): publish_mqtt("mqtsc") station_names = signal('station_names') station_names.connect(notify_station_names) ### program change ## def notify_program_change(name, **kw): publish_mqtt("mqtpc") program_change = signal('program_change') program_change.connect(notify_program_change) ### program deleted ### def notify_program_deleted(name, **kw): publish_mqtt("mqtpc") program_deleted = signal('program_deleted') program_deleted.connect(notify_program_deleted) ### program toggled ### def notify_program_toggled(name, **kw): publish_mqtt("mqtpc") program_toggled = signal('program_toggled') program_toggled.connect(notify_program_toggled) ### Plugin 1 settings ### def notify_plugin1_change(name, **kw): publish_mqtt("mqtp1") option_change = signal('plugin1_change') option_change.connect(notify_plugin1_change) ### Plugin 2 settings ### def notify_plugin2_change(name, **kw): publish_mqtt("mqtp2") option_change = signal('plugin2_change') option_change.connect(notify_plugin2_change) ### Plugin 3 settings ### def notify_plugin3_change(name, **kw): publish_mqtt("mqtp3") option_change = signal('plugin3_change') option_change.connect(notify_plugin3_change) # # The following came from # http://www.raspberrypi.org/forums/viewtopic.php?f=32&t=22180 # Return CPU temperature as a character string def getCPUtemperature(): res = os.popen('vcgencmd measure_temp').readline() return(res.replace("temp=","").replace("'C\n","")) # Return RAM information (unit=kb) in a list # Index 0: total RAM # Index 1: used RAM # Index 2: free RAM def getRAMinfo(): p = os.popen('free') i = 0 while 1: i = i + 1 line = p.readline() if i==2: return(line.split()[1:4]) # Return % of CPU used by user as a character string def getCPUuse(): return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip(\ ))) # Return information about disk space as a list (unit included) # Index 0: total disk space # Index 1: used disk space # Index 2: remaining disk space # Index 3: percentage of disk used def getDiskSpace(): p = os.popen("df -h /") i = 0 while 1: i = i +1 line = p.readline() if i==2: return(line.split()[1:5]) import os # Return CPU temperature as a character string def getCPUtemperature(): res = os.popen('vcgencmd measure_temp').readline() return(res.replace("temp=","").replace("'C\n",""))