Beispiel #1
0
class Location(Subject):
    def __init__(self, name, service, view, data, caller):
        Subject.__init__(self)

        self.observers = []
        self.name = name
        self.caller = caller
        self.temperature = Temperature(None)
        self.rainfall = Rainfall(None)
        self.timestamp = None
        self.datestamp = None

        self.serviceType = service
        self.viewType = view
        self.dataType = data

        self.client = None
        self.timer = None
        self.setupClient()

    def register(self, newObserver):
        self.observers.append(newObserver)

    def unregister(self, deleteObserver):
        self.observers.remove(deleteObserver)

    def notifyObservers(self):
        for observer in self.observers:
            observer.update(self.temperature.getTemperature(),
                            self.rainfall.getAmount(), self.datestamp,
                            self.timestamp)

    def setupClient(self):
        if self.serviceType == "MelbWeather2":
            # set up client and timer
            self.client = WebClientMelb()
            self.timer = UpdateTimer(300, self.updateData)

            # update data for the first time, then start the timer
            self.updateData()
            self.timer.start()
        elif self.serviceType == "WeatherTimeLapse":
            # set up client and timer
            incompatibleClient = WebClientTimeLapse()
            self.client = WebClientTimelapseAdapter(incompatibleClient)
            self.timer = UpdateTimer(2, self.updateData)

            # update data for the first time, then start the timer
            self.updateData()
            self.timer.start()
        else:
            print "Web Client Setup Error: web client name not found"

    """
    Updates data of the location's attributes from the WebClient
    """

    def updateData(self):
        locInfo = self.client.getWeatherData(self.name)
        self.setTemperature(locInfo[0])
        self.setRainfall(locInfo[1])
        self.setDatestamp(locInfo[2])
        self.setTimestamp(locInfo[3])
        self.notifyObservers()

    """
    Removes the location object from the location collection when a monitor is shut down
    """

    def removeLocation(self):
        self.caller.removeFromCollection(self)

    """
    Stops the timer by calling cancel()
    """

    def stopTimer(self):
        self.timer.cancel()

    """
    Getters
    """

    def getName(self):
        return self.name

    def getTemperature(self):
        return self.temperature.getTemperature()

    def getRainfall(self):
        return self.rainfall.getAmount()

    def getTimeStamp(self):
        return self.timestamp

    def getDateStamp(self):
        return self.datestamp

    """
    Setters
    """

    def setTemperature(self, newTemperature):
        self.temperature.setTemperature(newTemperature)

    def setRainfall(self, newAmount):
        self.rainfall.setAmount(newAmount)

    def setTimestamp(self, newTimestamp):
        self.timestamp = newTimestamp

    def setDatestamp(self, newDatestamp):
        self.datestamp = newDatestamp
Beispiel #2
0
class Main:
    load_dotenv()

    def __init__(self):
        # self.URL = "http://192.168.179.227:5001"
        self.URL = "https://pruetpiflask.azurewebsites.net"
        self.token = self.login()
        self.temp_sensor = Temperature()
        self.outlets = Power()
        self.tz = pytz.timezone('US/Central')

        # default state
        self.state = {
            "Temperature": 0,
            "pH": 0,
            "Light_UV_On": True,
            "Light_Refugium_On": True,
            "GasInjection_On": True,
            "Heater_On": True,
            "Pump_Power": 3
        }

        asyncio.run(self.main())

    async def main(self):
        await asyncio.gather(self.iot_hub_login(), self.get_settings())

        # set the mesage received handler on the client
        self.device_client.on_message_received = self.message_received_handler
        loop = asyncio.get_running_loop()
        user_finished = loop.run_in_executor(None, self.stdin_listener)

        # Wait for user to indicate they are done listening for messages
        await user_finished

        # Finally, disconnect
        await self.device_client.disconnect()

    def set_heater_outlet(self):
        if not self.settings["Heater"]["Enabled"]:
            self.outlets.power_off("Heater")
            print("Heater is disabled")
        else:
            min_temp = self.settings["Heater"]["MinTemp"]
            max_temp = self.settings["Heater"]["MaxTemp"]
            current_temp = self.temp_sensor.getTemperature()
            turn_on = True

            if min_temp > current_temp:
                turn_on = True
            elif current_temp > max_temp:
                turn_on = False

            if turn_on:
                self.outlets.power_on("Heater")
            else:
                self.outlets.power_off("Heater")

            print("Temp: {}, Heater On: {}".format(current_temp, turn_on))
            self.state["Heater_On"] = turn_on
            self.state["Temperature"] = current_temp

    def set_timed_outlets(self):
        current_time = datetime.now(self.tz)
        timed_outlets = ["GasInjection", "Light_Refugium", "Light_UV"]

        for outlet in timed_outlets:
            if not self.settings[outlet]["Enabled"]:
                self.outlets.power_off(outlet)
                print("{} is disabled".format(outlet))
            else:
                time_on = self.settings[outlet]["TimeOn"]
                timer = self.settings[outlet]["Timer"]

                turn_on = self.check_timer(current_time, time_on, timer)

                if turn_on:
                    self.outlets.power_on(outlet)
                else:
                    self.outlets.power_off(outlet)

                print("{} turned on: {}".format(outlet, turn_on))
                self.state[outlet + "_On"] = turn_on

    # Check to see if outlet should be turned on or off
    # Applies to CO2, UV light and refugium light
    def check_timer(self, current_time, time_on, timer):
        h_now, m_now = [current_time.hour, current_time.minute]
        h_setting, m_setting = [int(t) for t in time_on.split(":")]
        h_timer, m_timer = [int(t) for t in timer.split(":")]

        minutes_now = h_now * 60 + m_now
        minutes_start = h_setting * 60 + m_setting
        minutes_timer = h_timer * 60 + m_timer
        minutes_end = minutes_start + minutes_timer

        if minutes_start <= minutes_now <= minutes_end:
            return True
        elif (minutes_end >= 1440) and (minutes_now <= minutes_end - 1440):
            return True
        else:
            return False

    def login(self):
        headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
        flask_login = json.dumps({
            "username": os.getenv("FLASK_USERNAME"),
            "password": os.getenv("FLASK_PASSWORD")
        })

        url = self.URL + "/login"
        token = json.loads(
            requests.post(url=url, data=flask_login, headers=headers).text)

        print("Logged in successfully")

        return token

    async def get_settings(self):
        headers = {"Authorization": "Bearer " + self.token["access_token"]}

        url = self.URL + "/settings/get"
        settings = requests.get(url=url, headers=headers)

        self.settings = json.loads(settings.text)
        print("Settings retrieved successfully")

        self.set_timed_outlets()
        self.set_heater_outlet()

    async def iot_hub_login(self):
        try:
            # The client object is used to interact with your Azure IoT hub.
            # module_client = IoTHubModuleClient.create_from_edge_environment()
            # IoTHubModuleClient.create_from_edge_environment()
            conn_str = os.getenv("IOT_CONN_STRING")
            self.device_client = IoTHubDeviceClient. \
                create_from_connection_string(conn_str)

            # connect the client.
            await self.device_client.connect()
            print("Connected to IoTHub")
        except Exception as e:
            print("Unexpected error %s " % e)
            raise

    # define behavior for receiving a message
    # Calls cosmos to get updated settings due to a saved change
    async def message_received_handler(self, message):
        print("the data in the message received was ")
        print(message.data)

        await asyncio.gather(self.get_settings())

        self.post_state()

    def post_state(self):
        headers = {
            "Authorization": "Bearer " + self.token["access_token"],
            'Content-Type': 'application/json'
        }

        url = self.URL + "/state/post"
        payload = json.dumps(self.state)

        settings = requests.post(url=url, data=payload, headers=headers)

    # define behavior for halting the application
    def stdin_listener(self):
        while True:
            self.set_timed_outlets()
            self.set_heater_outlet()
            self.post_state()
            print(self.state, datetime.now())
            time.sleep(60)