Exemplo n.º 1
0
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))
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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)))
Exemplo n.º 4
0
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')

Exemplo n.º 5
0
# 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\""
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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'])
Exemplo n.º 8
0
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):
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
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
Exemplo n.º 12
0
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()