示例#1
0
 async def on_message(self, topic, msg, retain):
     """
     Changes the state of the pump.
     In switch mode a safety shutdown coro will be started.
     In repeating mode only the state of the pump gets changed.
     """
     print("on_message", topic, msg, retain, self._repeating_mode)
     if retain is True:
         await asyncio.sleep(
             2
         )  # so that other retained message about on_time,off_time and mode get processed first
     if self._repeating_mode is False:
         if self._off_coro is not None:
             asyncio.cancel(self._off_coro)
     if msg in _mqtt.payload_on:
         if (await super().on_message(topic, msg, retain)) is True:
             if self._repeating_mode is False:
                 self._off_coro = self._wait_off()
                 asyncio.get_event_loop().create_task(self._off_coro)
     elif msg in _mqtt.payload_off:
         if (await super().on_message(topic, msg, retain)) is False:
             if self._repeating_mode is False:
                 self._off_coro = self._wait_off()
                 asyncio.get_event_loop().create_task(
                     self._off_coro)  # try again
     else:
         await _log.asyncLog("error",
                             "unsupported payload: {!s}".format(msg))
         return False
     return True
示例#2
0
 async def on_message(self, topic, msg, retain):
     if retain is True:
         return False
     m = memoryview(topic)
     if m[-4:] == b"/set":
         return False
     if m == memoryview(self._topic)[:-2]:
         print("received amount", msg)
         self._icomp = int(msg)
         # no return so it can end if 0 components are expected
     elif self._icomp is None:
         await _log.asyncLog("error", "Need amount of components first")
         return False
     else:
         if type(msg) != dict:
             await _log.asyncLog("error", "Received config is no dict")
             return False
         name = topic[topic.rfind("/") + 1:]
         del topic
         gc.collect()
         _log.info("received config for component",
                   name,
                   ":",
                   msg,
                   local_only=True)
         if name in self._rcomp:
             # received config already, typically happens if process was
             # interrupted by network error
             return False
         self._rcomp.append(name)
         self._saveComponent(name, msg)
         await config.registerComponent(name, msg)
     if len(self._rcomp) == self._icomp:  # received all components
         asyncio.cancel(self._watcher_coro)
     return False
示例#3
0
 async def _read(self):
     a = time.ticks_us()
     p = self._ppin
     if p is not None:
         p.value(1)
     vol = self._adc.readVoltage()
     if self.DEBUG is True:
         print("#{!s}, V".format(self.getTopic(SENSOR_BINARY_MOISTURE)[-1]), vol)
     if p is not None:
         p.value(0)
     if vol >= self._cv:
         state = False
         if self._lv != state:
             # dry
             if self._pub_coro is not None:
                 asyncio.cancel(self._pub_coro)
             self._pub_coro = _mqtt.publish(self.getTopic(SENSOR_BINARY_MOISTURE), "OFF", qos=1,
                                            retain=True, timeout=None, await_connection=True)
             asyncio.get_event_loop().create_task(self._pub_coro)
         self._lv = state
     else:
         state = True
         if self._lv != state:
             # wet
             if self._pub_coro is not None:
                 asyncio.cancel(self._pub_coro)
             self._pub_coro = _mqtt.publish(self.getTopic(SENSOR_BINARY_MOISTURE), "ON", qos=1,
                                            retain=True, timeout=None, await_connection=True)
             asyncio.get_event_loop().create_task(self._pub_coro)
         self._lv = state
     b = time.ticks_us()
     if WaterSensor.DEBUG:
         print("Water measurement took", (b - a) / 1000, "ms")
示例#4
0
 async def _preprocessor(self,
                         coroutine,
                         *args,
                         timeout=None,
                         await_connection=True):
     coro = None
     start = time.ticks_ms()
     i = 0 if len(args) == 4 else 1  # 0: publish, 1:(un)sub
     try:
         while timeout is None or time.ticks_diff(time.ticks_ms(),
                                                  start) < timeout * 1000:
             if not await_connection and not self._isconnected:
                 return False
             if self._ops_coros[i] is coro is None:
                 coro = self._operationTimeout(coroutine, *args, i=i)
                 asyncio.get_event_loop().create_task(coro)
                 self._ops_coros[i] = coro
             elif coro:
                 if self._ops_coros[i] != coro:
                     return True  # published
             await asyncio.sleep_ms(20)
         _log.debug("timeout on",
                    "(un)sub" if i else "publish",
                    args,
                    local_only=True)
         self.__timedout += 1
     except asyncio.CancelledError:
         raise  # the caller should be cancelled too
     finally:
         if coro and self._ops_coros[i] == coro:
             async with self.lock:
                 asyncio.cancel(coro)
             return False
         # else: returns value during process
     return False
示例#5
0
 async def _connected_handler(self, client):
     try:
         await self.publish(self.getDeviceTopic(
             config.MQTT_AVAILABILITY_SUBTOPIC),
                            "online",
                            qos=1,
                            retain=True)
         # if it hangs here because connection is lost, it will get canceled when reconnected.
         if self.__first_connect is True:
             # only log on first connection, not on reconnect as nothing has changed here
             await _log.asyncLog(
                 "info",
                 str(os.name if platform == "linux" else os.uname()))
             await _log.asyncLog(
                 "info", "Client version: {!s}".format(config.VERSION))
             self.__first_connect = False
         elif self.__first_connect is False:
             await _log.asyncLog("debug", "Reconnected")
             # resubscribe topics because clean session is used
             if self._sub_coro is not None:
                 asyncio.cancel(self._sub_coro)
             self._sub_coro = self._subscribeTopics()
             asyncio.get_event_loop().create_task(self._sub_coro)
         for cb in self._reconnected_subs:
             res = cb(client)
             if type(res) == type_gen:
                 await res
         self._connected_coro = None
     except asyncio.CancelledError:
         if self._sub_coro is not None:
             asyncio.cancel(self._sub_coro)
示例#6
0
 async def off(self, extended_switch, component, component_on,
               component_off):
     """Turn device off"""
     if self._coro is not None:
         asyncio.cancel(self._coro)
     else:
         await component_off()
     return True
示例#7
0
 async def _remove(self):
     """Will be called if the component gets removed"""
     # Cancel any loops/asyncio coroutines started by the component
     try:
         asyncio.cancel(self._loop_coro)
     except Exception:
         pass
     await super()._remove()
示例#8
0
    async def _kill_task(self):
        if self.task is not None:
            await d(0)  # the task has to be started, otherwise cancel will block  todo: remove if possible
            cancel(self.task)
            await d(0)  # be sure it gets killed

        io.oled.fill(0)  # prepare oled for next task
        self._area = None  # no area in use
示例#9
0
def stop(leds, coros):
    global running
    running = False
    while coros:
        asyncio.cancel(coros.pop())
    # Remove power from external hardware
    for led in leds:
        led.off()
    Latency(200)  # Slow down scheduler to conserve power
示例#10
0
 async def _connected(self, client):
     _log.debug("mqtt connected", local_only=True)
     self.__reconnects += 1
     if self.__last_disconnect is not None:
         self.__downtime += (time.ticks_ms() -
                             self.__last_disconnect) / 1000
     self.__last_disconnect = None
     if self._connected_coro is not None:
         # processed subscriptions would have to be done again anyway
         asyncio.cancel(self._connected_coro)
     self._connected_coro = self._connected_handler(client)
     asyncio.get_event_loop().create_task(self._connected_coro)
示例#11
0
 async def off(self):
     """Turn switch off. Can be used by other components to control this component"""
     if self.lock.locked() is True and self._wfl is False:
         return False
     async with self.lock:
         res = await self._off(
         )  # if _off() returns True the value should be published
         if res is True:
             self._setState(False)
             if self._pub_task:
                 asyncio.cancel(self._pub_task)
                 self._pub_task = None
             self._pub_task = asyncio.get_event_loop().create_task(
                 self.__publish("OFF"))
         return res
示例#12
0
    def changeto(self, r: int, g: int, b: int, time=0, loop_cmd=False):
        self.looping = loop_cmd
        for action in self.current_action:
            try:
                asyncio.cancel(action)
            except AttributeError as e:
                if "pend_throw" in e.args[0]:
                    continue
                else:
                    raise

        self.current_action = (self.transition(r, time, self.RED),
                               self.transition(g, time, self.GREEN),
                               self.transition(b, time, self.BLUE))
        for action in self.current_action:
            self.loop.create_task(action)
示例#13
0
	def run_until_any(self, coros):
		stopcoros = []
		done = []
		pending = list(coros)
		for coro in coros:
			def stopper(coro):
				yield from coro
				pending.remove(coro)
				done.append(coro)
				yield asyncio.StopLoop(0)
			stopcoro = stopper(coro)
			stopcoros.append(stopcoro)
			self.call_soon(stopcoro)
		self.run_forever()
		for stopcoro in stopcoros:
			asyncio.cancel(stopcoro)
		return done, pending
示例#14
0
def heartbeat(enabled=True):
    """Show LED indicator that the async loop is running."""
    global _heartbeat_coroutine
    blue_led = pyb.LED(4)  # blue

    if enabled and (_heartbeat_coroutine is None):
        # Start
        async def heartbeat_task():
            while True:
                blue_led.on()
                await asyncio.sleep_ms(HEARTBEAT_PULSE)
                blue_led.off()
                await asyncio.sleep_ms(HEARTBEAT_PERIOD - HEARTBEAT_PULSE)
        _heartbeat_coroutine = heartbeat_task()
        upyt.sched.loop.create_task(_heartbeat_coroutine)

    elif (not enabled) and (_heartbeat_coroutine is not None):
        # Stop
        asyncio.cancel(_heartbeat_coroutine)
        blue_led.off()
        _heartbeat_coroutine = None
示例#15
0
 async def changeMode(self, topic, msg, retain):
     print("changeMode", topic, msg, retain, self._repeating_mode)
     if msg not in _mqtt.payload_on and msg not in _mqtt.payload_off:
         raise ValueError("unsupported payload {!r}".format(msg))
     if msg in _mqtt.payload_on:
         if self._repeating_mode is True:
             # already on
             return True
         elif self._repeating_mode is False:
             await super().on_message(self._topic, "OFF", retain)
             self._off_coro = self._repeating()
             asyncio.get_event_loop().create_task(self._off_coro)
     elif msg in _mqtt.payload_off:
         if self._off_coro is not None:
             asyncio.cancel(self._off_coro)  # will shut down pump
             self._off_coro = None
         if self._repeating_mode is True:
             return True
         elif self._repeating_mode is False:
             await super().on_message(self._topic, "OFF", retain)
             return True
     return True
示例#16
0
async def run(s_sock, loop, spectrum, np, np_state):
    coroColorChange = changeNeoPixelColor(spectrum, np)
    poller = select.poll()
    poller.register(s_sock, select.POLLIN)
    while True:
        res = poller.poll(1)  # 1ms block
        if res:  # Only s_sock is polled
            conn, addr = s_sock.accept()  # get client socket
            request = conn.recv(1024)
            request = str(request)
            led_on = request.find('/?led=on')
            led_off = request.find('/?led=off')
            if led_on == 6 and np_state == "OFF":
                np_state = "ON"
                loop.create_task(coroColorChange)
            if led_off == 6 and np_state == "ON":
                np_state = "OFF"
                asyncio.cancel(coroColorChange)
                setNeoPixel(np, 0, 0, 0)
                coroColorChange = changeNeoPixelColor(spectrum, np)
            # Implies if led_on and "ON", dont change state
            # Implies if led_off and "OFF", dont change state
            loop.create_task(sendWebPage(conn, np_state))
        await asyncio.sleep_ms(200)