class Job(): def __init__(self, commandList): self.__commandList = commandList config = json.load(open('./config.json', 'r')) logFile = "./log/{}".format(config["appName"]) logger = Logger(config["appName"], config["logLevel"], filename=logFile) port = 8883 self.__topic = config["topic"] self.__mqtt = Mqtt(logger, config["endPoint"], port, config["rootCA"], config["certificate"], config["privateKey"], config["clientId"]) self.__mqtt.subscribe(self.__topic + "/Request", self.__callback) self.__result = None self.__loop() def __callback(self, client, userdata, message): print(self) p = json.loads(message.payload) if ("command" in p): command = p["command"] param = None if ("param" in p): param = p["param"] for key in self.__commandList.keys(): if (command == key): self.__result = self.__commandList[key](param) return def __loop(self): while True: time.sleep(0.5) if (self.__result is None): continue payload = {"message": self.__result} self.__result = None self.__mqtt.publish(self.__topic + "/Response", json.dumps(payload))
class Producer(): def __init__(self): self.__topic = "$aws/rules/audio_transmission_rule/topic/audio_transmission" root_ca = "./certs/RootCA.pem" cert = "./certs/xxxxxxxxxx-certificate.pem.crt" key = "./certs/xxxxxxxxxx-private.pem.key" endpoint = "xxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com" self.__mqtt = Mqtt(root_ca, key, cert, endpoint) def send(self, data): now = datetime.now() # 時刻とデータの結合 ts = now.timestamp() ts = struct.pack('<d', ts) transfer_data = ts + data try: self.__mqtt.publish(self.__topic, transfer_data) print("publish {}byte".format(len(transfer_data))) except Exception as e: print("Exception: {}", e.args)
class Producer(): def __init__(self): self.__topic = "topic/audio_transmission" root_ca = "./certs/RootCA.pem" key = "./certs/xxxxxxxx-private.pem.key" cert = "./certs/xxxxxxxx-certificate.pem.crt" endpoint = "xxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com" self.__mqtt = Mqtt(root_ca, key, cert, endpoint) def send(self, data): now = datetime.now().strftime('%Y-%m-%dT%H:%M:%S') b64_data = base64.b64encode(data) raw_data = b64_data.decode() # デバッグ用にデータ削減 #raw_data = raw_data[0:40] payload = json.dumps({ "timestamp": now, "raw_data": raw_data }) self.__mqtt.publish(self.__topic, payload) print("publish {}byte".format(len(payload)))
import os import sys from mqtt import Mqtt BROKERHOST = os.getenv('MQTTHOST') BROKERPORT = int(os.getenv('MQTTPORT')) USERNAME = os.getenv('MQTTUSERNAME') PASSWORD = os.getenv('MQTTPASSWORD') mqtt = Mqtt(BROKERHOST, BROKERPORT, USERNAME, PASSWORD) mqtt.waitForConnection() mqtt.publish('failcloud/test/testPublish', 'hi hello')
# Ajout ou suppression du relay si POST confirm = form.getvalue("confirm") topic = form.getvalue("topic") idRelay = form.getvalue("idRelay") nameRelay = form.getvalue("nameRelay") brightness = form.getvalue("brightness") html = """<!DOCTYPE html> <head> <title>Config MQTT pour Home-Assistant</title> </head> <body> """ if confirm: Mqtt.publish(confirm, None, True) elif topic: html += '<br /><form action="/init.py" method="post">' html += "Confirmez-vous la suppression du topic: " + topic + " ?" html += '<input type="hidden" name="confirm" value="' + topic + '" />' html += '<input type="submit" name="suppr" value="Supprimer" />' html += "</form><br /><br /><hr>" elif idRelay and nameRelay: if re.match(r"^r[0-9]{2}$", idRelay) and not brightness or re.match(r"^d[0-9]c[0-9]$", idRelay) and brightness: topic = Constantes.mqttTopic + "/light/" + idRelay + "/config" payload = "{ \"~\": \"" + Constantes.mqttTopic + "/light/" + idRelay + "\"" # TODO payload += ", \"name\": \"" + nameRelay + "\"" payload += ", \"unique_id\": \"" + idRelay + "_light\"" payload += ", \"command_topic\": \"~/set\"" payload += ", \"state_topic\": \"~/state\"" payload += ", \"schema\": \"json\""
class Irrigate: def __init__(self, configFilename): self.startTime = datetime.now() self.logger = self.getLogger() self.logger.info("Reading configuration file '%s'..." % configFilename) self.init(configFilename) self.terminated = False self.mqtt = Mqtt(self) self.createThreads() self._intervalDict = {} self.sensors = {} def start(self, test=True): if self.cfg.mqttEnabled: self.logger.info("Starting MQTT...") self.mqtt.start() self.logger.debug("Starting worker threads...") for worker in self.workers: self.logger.info("Starting worker thread '%s'." % worker.getName()) worker.setDaemon(test) worker.start() self.logger.debug("Starting sensors...") for sch in self.cfg.schedules.values(): if sch.sensor != None: sensorHandler = sch.sensor.handler try: if not sensorHandler.started: self.logger.info("Starting sensor '%s'." % format(sensorHandler)) sensorHandler.start() self.sensors[sch.sensor.type] = sensorHandler except Exception as ex: self.logger.error("Error starting sensor '%s': '%s'." % (sch.sensor.type, format(ex))) self.logger.info("Starting timer thread '%s'." % self.timer.getName()) self.timer.start() def init(self, cfgFilename): self.cfg = config.Config(self.logger, cfgFilename) self.valves = self.cfg.valves self.q = queue.Queue() def createThreads(self): self.workers = [] for i in range(self.cfg.valvesConcurrency): worker = Thread(target=self.valveThread, args=()) worker.setDaemon(False) worker.setName("ValveTh%s" % i) self.workers.append(worker) self.timer = Thread(target=self.timerThread, args=()) self.timer.setDaemon(True) self.timer.setName("TimerTh") def evalSched(self, sched, timezone, now): todayStr = calendar.day_abbr[datetime.today().weekday()] if not todayStr in sched.days: return False lat, lon = self.cfg.getLatLon() if sched.seasons != None and not self.getSeason(lat) in sched.seasons: return False hours, minutes = sched.start.split(":") startTime = datetime.now() if sched.type == 'absolute': startTime = startTime.replace(hour=int(hours), minute=int(minutes), second=0, microsecond=0, tzinfo=pytz.timezone(timezone)) else: sun = Sun(lat, lon) if sched.type == 'sunrise': startTime = sun.get_local_sunrise_time().replace( second=0, microsecond=0, tzinfo=pytz.timezone(timezone)) elif sched.type == 'sunset': startTime = sun.get_local_sunset_time().replace( second=0, microsecond=0, tzinfo=pytz.timezone(timezone)) if hours[0] == '+': hours = hours[1:] startTime = startTime + timedelta(hours=int(hours), minutes=int(minutes)) if hours[0] == '-': hours = hours[1:] startTime = startTime - timedelta(hours=int(hours), minutes=int(minutes)) if startTime == now: return True return False def getSeason(self, lat): month = datetime.today().month season = None if lat >= 0: if 3 <= month <= 5: season = "Spring" elif 6 <= month <= 8: season = "Summer" elif 9 <= month <= 11: season = "Fall" elif month == 12 or month <= 2: season = "Winter" else: if 3 <= month <= 5: season = "Fall" elif 6 <= month <= 8: season = "Winter" elif 9 <= month <= 11: season = "Spring" elif month == 12 or month <= 2: season = "Summer" return season def valveThread(self): while not self.terminated: try: irrigateJob = self.q.get(timeout=5) if irrigateJob.valve.handled: self.logger.warning( "Valve '%s' already handled. Returning to queue in 1 minute." % (irrigateJob.valve.name)) time.sleep(61) self.q.put(irrigateJob) else: valve = irrigateJob.valve valve.handled = True self.logger.info( "Irrigation cycle start for valve '%s' for %s minutes." % (valve.name, irrigateJob.duration)) duration = timedelta(minutes=irrigateJob.duration) valve.secondsLast = 0 valve.secondsRemain = duration.seconds initialOpen = valve.secondsDaily sensorDisabled = False openSince = None startTime = datetime.now() while startTime + duration > datetime.now(): # The following two if statements needs to be together and first to prevent # the valve from opening if the sensor is disable. if irrigateJob.sensor != None and irrigateJob.sensor.handler.started: try: holdSensorDisabled = irrigateJob.sensor.handler.shouldDisable( ) if holdSensorDisabled != sensorDisabled: sensorDisabled = holdSensorDisabled self.logger.info( "Suspend set to '%s' for valve '%s' from sensor" % (sensorDisabled, valve.name)) except Exception as ex: self.logger.error( "Error probing sensor (shouldDisable) '%s': %s." % (irrigateJob.sensor.type, format(ex))) if not valve.open and not valve.suspended and not sensorDisabled: valve.open = True openSince = datetime.now() valve.handler.open() self.logger.info("Irrigation valve '%s' opened." % (valve.name)) if valve.open and (valve.suspended or sensorDisabled): valve.open = False valve.secondsLast = (datetime.now() - openSince).seconds openSince = None valve.secondsDaily = initialOpen + valve.secondsLast initialOpen = valve.secondsDaily valve.secondsLast = 0 valve.handler.close() self.logger.info("Irrigation valve '%s' closed." % (valve.name)) if valve.open: valve.secondsLast = (datetime.now() - openSince).seconds valve.secondsDaily = initialOpen + valve.secondsLast if valve.enabled == False: self.logger.info( "Valve '%s' disabled. Terminating irrigation cycle." % (valve.name)) break if self.terminated: self.logger.warning( "Program exiting. Terminating irrigation cycle for valve '%s'..." % (valve.name)) break valve.secondsRemain = ((startTime + duration) - datetime.now()).seconds self.logger.debug("Irrigation valve '%s' Last Open = %ss. Remaining = %ss. Daily Total = %ss." \ % (valve.name, valve.secondsLast, valve.secondsRemain, valve.secondsDaily)) time.sleep(1) self.logger.info("Irrigation cycle ended for valve '%s'." % (valve.name)) if valve.open and not valve.suspended: valve.secondsLast = (datetime.now() - openSince).seconds valve.secondsDaily = initialOpen + valve.secondsLast if valve.open: valve.open = False valve.handler.close() self.logger.info( "Irrigation valve '%s' closed. Overall open time %s seconds." % (valve.name, valve.secondsDaily)) valve.handled = False self.q.task_done() except queue.Empty: pass self.logger.warning("Valve handler thread '%s' exited." % threading.currentThread().getName()) def queueJob(self, job): self.q.put(job) if job.sched != None: self.logger.info( "Valve '%s' job queued per sched '%s'. Duration %s minutes." % (job.valve.name, job.sched.name, job.duration)) else: self.logger.info( "Valve '%s' adhoc job queued. Duration %s minutes." % (job.valve.name, job.duration)) def everyXMinutes(self, key, interval, bootstrap): if not key in self._intervalDict.keys(): self._intervalDict[key] = datetime.now() return bootstrap if datetime.now() >= self._intervalDict[key] + timedelta( minutes=interval): self._intervalDict[key] = datetime.now() return True return False def timerThread(self): try: while True: now = datetime.now().replace(tzinfo=pytz.timezone( self.cfg.timezone), second=0, microsecond=0) if now.hour == 0 and now.minute == 0: for aValve in self.valves.values(): aValve.secondsDaily = 0 if self.everyXMinutes("idleInterval", self.cfg.telemIdleInterval, False) and self.cfg.telemetry: delta = (datetime.now() - self.startTime) uptime = ((delta.days * 86400) + delta.seconds) // 60 self.mqtt.publish("/svc/uptime", uptime) for valve in self.valves.values(): self.telemetryValve(valve) for sensor in self.sensors.keys(): self.telemetrySensor(sensor, self.sensors[sensor]) if self.everyXMinutes("activeinterval", self.cfg.telemActiveInterval, False) and self.cfg.telemetry: for valve in self.valves.values(): if valve.handled: self.telemetryValve(valve) if self.everyXMinutes("scheduler", 1, True): # Must not evaluate more or less than once every minute otherwise running jobs will get queued again for aValve in self.valves.values(): if aValve.enabled: if aValve.schedules != None: for valveSched in aValve.schedules.values(): if self.evalSched(valveSched, self.cfg.timezone, now): jobDuration = valveSched.duration if valveSched.sensor != None and valveSched.sensor.handler != None and valveSched.sensor.handler.started: try: factor = valveSched.sensor.handler.getFactor( ) if factor != 1: jobDuration = jobDuration * factor self.logger.info( "Job duration changed from '%s' to '%s' based on input from sensor." % (valveSched.duration, jobDuration)) except Exception as ex: self.logger.error( "Error probing sensor (getFactor) '%s': %s." % (valveSched.sensor.type, format(ex))) job = model.Job( valve=aValve, duration=jobDuration, sched=valveSched, sensor=valveSched.sensor) self.queueJob(job) time.sleep(1) except Exception as ex: self.logger.error( "Timer thread exited with error '%s'. Terminating Irrigate!" % format(ex)) self.terminated = True def telemetryValve(self, valve): statusStr = "enabled" if not valve.enabled: statusStr = "disabled" elif valve.suspended: statusStr = "suspended" elif valve.open: statusStr = "open" self.mqtt.publish(valve.name + "/status", statusStr) self.mqtt.publish(valve.name + "/dailytotal", valve.secondsDaily) self.mqtt.publish(valve.name + "/remaining", valve.secondsRemain) if valve.open: self.mqtt.publish(valve.name + "/secondsLast", valve.secondsLast) def telemetrySensor(self, name, sensor): prefix = "sensor/" + name + "/" statusStr = "Enabled" try: if sensor.shouldDisable(): statusStr = "Disabled" elif sensor.getFactor() != 1: statusStr = "Factored" self.mqtt.publish(prefix + "factor", sensor.getFactor()) telem = sensor.getTelemetry() if telem != None: for t in telem.keys(): self.mqtt.publish(prefix + t, telem[t]) except Exception as ex: statusStr = "Error" self.mqtt.publish(prefix + "status", statusStr) def getLogger(self): formatter = logging.Formatter( fmt='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') handler = logging.FileHandler('log.txt', mode='w') handler.setFormatter(formatter) screen_handler = logging.StreamHandler(stream=sys.stdout) # screen_handler.setFormatter(formatter) logger = logging.getLogger("MyLogger") logger.setLevel(logging.DEBUG) logger.addHandler(handler) logger.addHandler(screen_handler) return logger
import ubinascii import time import machine import json from connect import Connect from led_pwm import LedPwm from lcd import Lcd from temperature_dht11 import TemperatureSensor as Dht from mqtt import Mqtt dht = Dht(4) led = LedPwm(2) lcd = Lcd(spi=1, cs=2, dc=15, rst=0, bl=12) config = json.loads(open('config.json').read()) client_id = ubinascii.hexlify(machine.unique_id()) try: mqtt = Mqtt(client_id, config['broker_ip']) except: mqtt = False while True: # Connect to wifi Connect.check_and_reconnect() try: data = { 'temperature': dht.read_temp_and_hum()[0], 'humidity': dht.read_temp_and_hum()[1] } print(str(time.localtime()) + ' ' + str(data)) if not mqtt: try: mqtt = Mqtt(client_id, config['broker_ip'])
from mqtt import Mqtt logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO) ROUTERPASSWORD = os.getenv('ROUTERPASSWORD') BROKERHOST = os.getenv('MQTTHOST') BROKERPORT = int(os.getenv('MQTTPORT')) USERNAME = os.getenv('MQTTUSERNAME') PASSWORD = os.getenv('MQTTPASSWORD') mqtt = Mqtt(BROKERHOST, BROKERPORT, USERNAME, PASSWORD, topics=[]) mqtt.waitForConnection() mqtt.publish('failcloud/connectbot', 'Hello from experiment.mqtt4connectbox python script!') # via https://github.com/fabaff/python-connect-box/blob/master/example.py buffer = {} def aliasify(dev): if dev.mac == '8C:45:00:69:E9:17': dev.hostname = 'IKEA TRADFRI' elif dev.mac == 'A0:28:ED:86:36:46': dev.hostname = 'think7plus' return dev def createBuffer(devices):
class Main: """ Main class for full logic this program. Run this class by call 'main' """ def __init__(self): self.wifi = Wifi( ssid=CONFIG["WIFI_SSID"], password=CONFIG["WIFI_PASSWORD"], gmt=CONFIG["GMT"], ) self.mqtt = Mqtt( ip=CONFIG["MQTT_IP"], user=CONFIG["MQTT_USER"], password=CONFIG["MQTT_PASS"], keepalive=CONFIG["MQTT_KEEPALIVE"], ) self.mqtt.set_last_will( topic=CONFIG["LW_TOPIC"], msg=ujson.dumps(CONFIG["LW_MSG_OFFLINE"]), retain=CONFIG["LW_RETAIN"], qos=CONFIG["LW_QOS"], ) self.dht22 = DHT22(Pin(CONFIG["DHT22_PIN"])) self.is_sending_synchronizate = False def _send_data(self): """ Meas dht22 data and publish temperature and humidity via mqtt. """ try: local_time = localtime()[:-2] # remove mili and micro seconds self.dht22.measure() # important for take actual values temp = { "name": CONFIG["NAME_DEVICE"], "date": local_time, "value": str(self.dht22.temperature()), } hum = { "name": CONFIG["NAME_DEVICE"], "date": local_time, "value": str(self.dht22.humidity()), } self.mqtt.publish(CONFIG["TOPIC_TEMP"], ujson.dumps(temp), retain=True) self.mqtt.publish(CONFIG["TOPIC_HUM"], ujson.dumps(hum), retain=True) except Exception as ex: print("\t_send_data unable to send `{}`".format(ex)) pass # Main loop def main(self): """ Main loop. """ start = ticks_ms() first_start = True # defined for timing interval while True: sleep_ms(50) ######## WIFI CHECK if not self.wifi.is_connected(): self.is_sending_synchronizate = False self.mqtt.disconnect() self.wifi.connect() # infinity loop for connecting to wifi ######## MQTT CHECK if not self.mqtt.is_connected(): self.is_sending_synchronizate = False if not self.mqtt.connect(): sleep(10) continue else: # on connect self.mqtt.publish( CONFIG["LW_TOPIC"], ujson.dumps(CONFIG["LW_MSG_ONLINE"]), retain=True, ) ######## INTERVAL & SEND DATA ### check sending data with synchro time if CONFIG["SYNC_SEND_DATA"]: # if synchronizate sending setted # waiting on whole minute with 0 seconds if not self.is_sending_synchronizate: second = localtime()[5] if second != 0: # if not synchronizated continue self.is_sending_synchronizate = True #### Sending data # timing sending data this way is not the best solution # if you want excelent timig. Find better solution. diff = ticks_diff(ticks_ms(), start) # ms if first_start or diff >= CONFIG["INTERVAL_SEND_DATA"] * 1000: first_start = False start = ticks_ms() self._send_data()
etat = form.getvalue("etat") brightness = form.getvalue("brightness") topic = Constantes.mqttTopic + "/" + change + "/" + uid + "/state" payload = '{ ' + '"state": "' if etat == "0": payload += 'OFF' else: payload += 'ON' payload += '"' if uid.lower().startswith("d"): if not brightness: dimmer = uid[1:2] channel = uid[3:] # Si la valeur n'est pas renseignée on prend la dernière en statut req = requests.get("http://" + Constantes.ipxHost + "/api/xdevices.json?key=" + Constantes.ipxApiKey + "&Get=G") jsonStatus = json.loads(req.text) numStatus = (int(dimmer)-1)*4+int(channel) brightness = str(jsonStatus['G' + str(numStatus)]['Valeur']) payload += ', "brightness": ' + str(int(int(brightness)*2.55)) payload += ' }' print("type: ") print(change) print("\ntopic: ") print(topic) print("\npayload: ") print(payload) Mqtt.publish(topic, payload, True)
class Controller: #Safe box temperature minimum temperature min_temp = 20 #Safe box temperature maximum temperature max_temp = 21 #Safe box temperature current_in_temp = 0 #Safe box humidity current_in_hum = 0 #Air conditioner temperature change rate current_in_air_cond_state = 0 #External temperature current_ex_temp = 0 #Daily sensors sample daily_samples = list() #MQTT client mqtt = None #Path to application folder ROOT_PATH = "/home/franklin/Desktop/Projetos/pgcc008-problem01/web-application/" def __init__(self): #Starts and connect MQTT client to AWS MQTT Broker self.mqtt = Mqtt() self.mqtt.connect() #Stats loading data self.loadData() #Refresh all data readed to a new sample def refreshData(self): #Gets read time now = datetime.now() current_time = now.strftime("%H:%M:%S") #Data update check newData = False #Checks current internal temperature changes and updates if self.current_in_temp != self.mqtt.dataSubscribed[0]: self.current_in_temp = self.mqtt.dataSubscribed[0] print( "[SERVER at", current_time + "] Internal temperature: " + str(self.current_in_temp) + "C") newData = True #Checks current internal humidity changes and updates if self.current_in_hum != self.mqtt.dataSubscribed[1]: self.current_in_hum = self.mqtt.dataSubscribed[1] print( "[SERVER at", current_time + "] Internal humidity: " + str(self.current_in_hum) + "%") newData = True #Checks current internal air conditioner changes and updates if self.current_in_air_cond_state != self.mqtt.dataSubscribed[2]: self.current_in_air_cond_state = self.mqtt.dataSubscribed[2] if self.current_in_air_cond_state == 0.0: print("[SERVER at", current_time + "] Air conditioning state: off") elif self.current_in_air_cond_state > 0.0: print( "[SERVER at", current_time + "] Air conditioning state: heating (" + str(self.current_in_air_cond_state) + "C/min)") elif self.current_in_air_cond_state < 0.0: print( "[SERVER at", current_time + "] Air conditioning state: cooling (" + str(self.current_in_air_cond_state) + "C/min)") newData = True #Checks current external temperature changes and updates if self.current_ex_temp != self.mqtt.dataSubscribed[3]: self.current_ex_temp = self.mqtt.dataSubscribed[3] print( "[SERVER at", current_time + "] External temperature: " + str(self.current_ex_temp) + "C") newData = True #Save a new daily sample sample = [ current_time, self.current_in_temp, self.current_in_hum, self.current_in_air_cond_state, self.current_ex_temp ] self.saveData(sample) #Refresh graphs if newData == True or int(now.strftime("%S")) == 0: self.plotCharts() #Saves daily samples on a file def saveData(self, sample): today = date.today() current_date = today.strftime("%Y/%m/%d") #Path to daily samples file path = self.ROOT_PATH + "files/" + current_date.replace('/', '-') + ".csv" #Starts a new daily sample file fileExists = True if not os.path.isfile(path): fileExists = False self.daily_samples = list() #Open daily sample file and write new sample with open(path, 'a') as file: file_writer = csv.writer(file) if fileExists is False: file_writer.writerow([ "time", "in_temp", "in_hum", "in_air_cond_state", "ex_temp" ]) file_writer.writerow(sample) #Saves sample self.daily_samples.append(sample) #Load current daily samples if exists def loadData(self): today = date.today() day = today.strftime("%Y/%m/%d") #Path to daily samples file path = self.ROOT_PATH + "files/" + day.replace('/', '-') + ".csv" #Reads daily samples file and saves data on daily_samples list self.daily_samples = list() if os.path.isfile(path): with open(path, 'r') as file: file_reader = csv.reader(file) firstRead = True for row in file_reader: if firstRead is True: firstRead = False else: sample = [ row[0], float(row[1]), float(row[2]), float(row[3]), float(row[4]) ] self.daily_samples.append(sample) nSamples = len(self.daily_samples) self.current_in_temp = self.daily_samples[nSamples - 1][1] self.current_in_hum = self.daily_samples[nSamples - 1][2] self.current_in_air_cond_state = self.daily_samples[nSamples - 1][3] self.current_ex_temp = self.daily_samples[nSamples - 1][4] self.mqtt.dataSubscribed[0] = self.current_in_temp self.mqtt.dataSubscribed[1] = self.current_in_hum self.mqtt.dataSubscribed[2] = self.current_in_air_cond_state self.mqtt.dataSubscribed[3] = self.current_ex_temp #Plots chats self.plotCharts() #Plots chats def plotCharts(self): time_axis = list() in_temp_axis = list() in_hum_axis = list() in_air_cond_state_axis = list() ex_temp_axis = list() #current_time = #Creates multiple y-axis for sample in self.daily_samples: time_axis_sample = int(sample[0][0:2]) + float( (int(sample[0][3:5]) * 60) + int(sample[0][6:8])) / 3600.0 time_axis.append(time_axis_sample) in_temp_axis.append(sample[1]) in_hum_axis.append(sample[2]) in_air_cond_state_axis.append(sample[3]) ex_temp_axis.append(sample[4]) #Plots all charts and save figure to show plt.plot(time_axis, in_temp_axis) plt.grid() plt.savefig(self.ROOT_PATH + "static/images/charts/in_temp.png", transparent=True) plt.clf() plt.plot(time_axis, ex_temp_axis) plt.grid() plt.savefig(self.ROOT_PATH + "static/images/charts/ex_temp.png", transparent=True) plt.clf() plt.plot(time_axis, in_hum_axis) plt.grid() plt.savefig(self.ROOT_PATH + "static/images/charts/in_hum.png", transparent=True) plt.clf() plt.plot(time_axis, in_air_cond_state_axis) plt.grid() plt.savefig(self.ROOT_PATH + "static/images/charts/in_air_cond_state.png", transparent=True) plt.clf() #Increase or decrease minimum temperature def changeMinTemp(self, increase): confirmation = False if increase is True: #Checks relation between minimum and maximum temperatures. if (self.min_temp + 1) < self.max_temp: self.min_temp = self.min_temp + 1 self.mqtt.publish("pgcc008/problem01/limit/min", self.min_temp) confirmation = True else: self.min_temp = self.min_temp - 1 self.mqtt.publish("pgcc008/problem01/limit/min", self.min_temp) confirmation = True if confirmation is True: now = datetime.now() current_time = now.strftime("%H:%M:%S") print( "[SERVER at", current_time + "] Internal temperature range: " + str(self.min_temp) + " to " + str(self.max_temp) + "C") return confirmation #Increase or decrease maximum temperature def changeMaxTemp(self, increase): confirmation = False if increase is True: #Checks relation between minimum and maximum temperatures. self.max_temp = self.max_temp + 1 self.mqtt.publish("pgcc008/problem01/limit/max", self.max_temp) confirmation = True else: if (self.max_temp - 1) > self.min_temp: self.max_temp = self.max_temp - 1 self.mqtt.publish("pgcc008/problem01/limit/max", self.max_temp) confirmation = True if confirmation is True: now = datetime.now() current_time = now.strftime("%H:%M:%S") print( "[SERVER at", current_time + "] Internal temperature range: " + str(self.min_temp) + " to " + str(self.max_temp) + "C") return confirmation #Returns temperature on display format def getTempFormatted(self, variable): if variable == "MIN": temp = self.min_temp elif variable == "MAX": temp = self.max_temp elif variable == "IN_TEMP": temp = self.current_in_temp elif variable == "EX_TEMP": temp = self.current_ex_temp temp_form = str(int(temp)) + 'º' if temp >= 0 and temp < 10: temp_form = '0' + str(int(temp)) + 'º' return temp_form #Returns humidity on display format def getHumFormatted(self): hum_form = str(int(self.current_in_hum)) + '%' if self.current_in_hum >= 0 and self.current_in_hum < 10: hum_form = '0' + str(int(self.current_in_hum)) + '%' return hum_form #Returns air conditioner on display format def getAirCondState(self): air_cond_state_form = "DES" if self.current_in_air_cond_state > 0.0: air_cond_state_form = "AQU" if self.current_in_air_cond_state < 0.0: air_cond_state_form = "RES" return air_cond_state_form
class States: #Safe box temperature current_in_temp = 20 #Safe box humidity current_in_hum = 50 #External temperature current_ex_temp = 20 #Air conditioner temperature change rate air_cond_interaction = 0.0 #Safe box temperature minimum temperature min_temp = 20 #Safe box temperature maximum temperature max_temp = 21 #MQTT client mqtt = None def __init__(self): #Gets args ap = argparse.ArgumentParser() ap.add_argument("-s", "--simulated", type=int, help="simulated environment") args = vars(ap.parse_args()) #Starts and connect MQTT client to AWS MQTT Broker self.mqtt = Mqtt() self.mqtt.connect() #Simulation case 1: #Internal temperature from NODEMCU #Internal humidity from potentiometer #Air conditioner from NODEMCU #External temperature from potentiometer if args["simulated"] == 1: self.internalSensor = SimulatedEnvironment(None) self.internalSensor.start() self.airCondControl = self.internalSensor self.externalSensor = self.internalSensor #Simulation case 2: #Internal temperature from NODEMCU #Internal humidity from DHT22 #Air conditioner from NODEMCU #External temperature from DHT22 elif args["simulated"] == 2: self.internalSensor = SimulatedEnvironment(Dht22(22)) self.internalSensor.start() self.airCondControl = self.internalSensor self.externalSensor = Dht22(23) self.externalSensor.start() #Simulation case 3: #Internal temperature from DHT22(1) #Internal humidity from DHT22(1) #Air conditioner from NODEMCU #External temperature from DHT22(2) else: self.internalSensor = Dht22(22) self.internalSensor.start() self.airCondControl = SimulatedEnvironment(None) self.airCondControl.start() self.externalSensor = Dht22(23) self.externalSensor.start() #Read initial data from sensors self.current_in_temp = self.internalSensor.read("IN_TEMP") self.current_in_hum = self.internalSensor.read("IN_HUM") self.current_ex_temp = self.externalSensor.read("EX_TEMP") #Publish initial data on respective topics self.mqtt.publish("pgcc008/problem01/sensor/internal/temperature", self.current_in_temp) self.mqtt.publish("pgcc008/problem01/sensor/internal/humidity", self.current_in_hum) self.mqtt.publish("pgcc008/problem01/sensor/internal/air_cond_state", self.air_cond_interaction) self.mqtt.publish("pgcc008/problem01/sensor/external/temperature", self.current_ex_temp) print("[DEVICE] Control System started") #Reads all sensors def readSensors(self): #Gets read time now = datetime.now() current_time = now.strftime("%H:%M:%S") #Checks update on temperature range and change this range. newRange = False #Minimum newData = self.mqtt.dataSubscribed[0] if newData != self.min_temp: self.min_temp = newData newRange = True #Maximum newData = self.mqtt.dataSubscribed[1] if newData != self.max_temp: self.max_temp = newData newRange = True if newRange is True: print( "[DEVICE at", current_time + "] Internal temperature range: " + str(self.min_temp) + " to " + str(self.max_temp) + "C") #Checks internal temperature change, updates and publish on topic next_in_temp = self.internalSensor.read("IN_TEMP") if next_in_temp != self.current_in_temp: self.current_in_temp = next_in_temp self.mqtt.publish("pgcc008/problem01/sensor/internal/temperature", self.current_in_temp) print( "[DEVICE at", current_time + "] Internal temperature: " + str(self.current_in_temp) + "C") #Checks internal humidity change, updates and publish on topic next_in_hum = self.internalSensor.read("IN_HUM") if next_in_hum != self.current_in_hum: self.current_in_hum = next_in_hum self.mqtt.publish("pgcc008/problem01/sensor/internal/humidity", self.current_in_hum) print( "[DEVICE at", current_time + "] Internal humidity: " + str(self.current_in_hum) + "%") #Checks external temperature change, updates and publish on topic next_ex_temp = self.externalSensor.read("EX_TEMP") if next_ex_temp != self.current_ex_temp: self.current_ex_temp = next_ex_temp self.mqtt.publish("pgcc008/problem01/sensor/external/temperature", self.current_ex_temp) print( "[DEVICE at", current_time + "] External temperature: " + str(self.current_ex_temp) + "C") #Sends air conditioner command def sendAirCondCommand(self, command): now = datetime.now() current_time = now.strftime("%H:%M:%S") previous_cond_interaction = self.air_cond_interaction air_cond_change_rate = 0.0 #Checks command to heating safe box if command == "heating": #Calculates Heating rate (minmum = 0.1C/min) air_cond_change_rate = 1 - ( (self.current_in_temp - self.current_ex_temp) * 0.05) if air_cond_change_rate < 0.0: air_cond_change_rate = 0.1 #Calculates Cooling rate (maximum = -0.1C/min) elif command == "cooling": air_cond_change_rate = 1 - ( (self.current_ex_temp - self.current_in_temp) * 0.05) air_cond_change_rate = -air_cond_change_rate if air_cond_change_rate > 0.0: air_cond_change_rate = -0.1 self.air_cond_interaction = float('%.2f' % air_cond_change_rate) #Checks change on cooling or heating rate, sends command to change temperature and publish on topic if previous_cond_interaction != self.air_cond_interaction: self.airCondControl.write(str(self.air_cond_interaction)) print( "[DEVICE at", current_time + "] Air conditioner state: " + command + " (" + str(self.air_cond_interaction) + "C/min)") self.mqtt.publish( "pgcc008/problem01/sensor/internal/air_cond_state", self.air_cond_interaction) #Finishs application def stop(self): #Turn off air conditioner self.sendAirCondCommand("off") #Stop all sensors self.internalSensor.stopRead() self.externalSensor.stopRead() self.airCondControl.stopRead() #Closes connection with MQTT broker self.mqtt.disconnect()