예제 #1
0
 def _configure_and_stream(
         self,
         config: dict[str, Any] | None) -> AsyncGenerator[DataEvent, None]:
     if config is None:
         return stream.empty()
     try:
         # Run all config steps in order (concat) and one at a time (task_limit=1). Drop the output. There is
         # nothing to compare them to (filter => false), then read all sensors of the bricklet and process them in
         # parallel (flatten).
         config_stream = stream.chain(
             stream.iterate(config["on_connect"])
             | pipe.starmap(lambda func, timeout: stream.just(func()) | pipe
                            .timeout(timeout))
             | pipe.concat(task_limit=1)
             | pipe.filter(lambda result: False),
             stream.iterate(config["config"].items())
             | pipe.starmap(self._parse_callback_configuration)
             | pipe.starmap(self._set_callback_configuration)
             | pipe.flatten()
             |
             pipe.map(lambda args: self._read_sensor(config["uuid"], *args))
             | pipe.flatten(),
         )
         return config_stream
     except NotConnectedError:
         # Do not log it
         raise
     except Exception:
         self._logger.exception("This should not happen.")
         raise
예제 #2
0
 def _read_device(config: dict[str, Any]) -> AsyncGenerator[Any, None]:
     on_read: partial
     timeout: float
     on_read, timeout = config["on_read"]
     if inspect.isasyncgenfunction(on_read.func):
         return stream.iterate(on_read()) | pipe.timeout(timeout)
     return (stream.repeat(config["on_read"], interval=config["interval"])
             | pipe.starmap(lambda func, timeout: stream.just(func()) | pipe
                            .timeout(timeout))
             | pipe.concat(task_limit=1))
예제 #3
0
 def _read_sensor(  # pylint: disable=too-many-arguments
     self, sid: int, interval: float, unit: str, topic: str, timeout: float
 ) -> AsyncGenerator[DataEvent, None]:
     if self.__uuid is None:
         raise SensorNotReady("You must enumerate the sensor before reading.")
     return (
         stream.repeat(stream.call(self._device.get_by_function_id, sid), interval=interval)
         | pipe.concat(task_limit=1)
         | pipe.timeout(timeout)
         | pipe.map(lambda value: DataEvent(sender=self.__uuid, topic=topic, value=value, sid=sid, unit=str(unit)))
     )
예제 #4
0
 def _configure_and_stream(
         self, config: dict[str, Any]) -> AsyncGenerator[DataEvent, None]:
     if config is None:
         return stream.empty()
     # Run all config steps in order (concat) and one at a time (task_limit=1). Drop the output. There is nothing to
     # compare them to (filter => false), then read the device.
     config_stream = stream.chain(
         stream.iterate(config["on_connect"])
         | pipe.starmap(lambda func, timeout: stream.just(func()) | pipe.
                        timeout(timeout))
         | pipe.concat(task_limit=1)
         | pipe.filter(lambda result: False),
         self._read_device(config)
         | pipe.map(lambda item: DataEvent(sender=config["uuid"],
                                           topic=config["topic"],
                                           value=item,
                                           sid=0,
                                           unit=config["unit"]))
         | finally_action.pipe(
             stream.call(self._clean_up, config["on_disconnect"])),
     ) | catch.pipe(TypeError, on_exc=self.on_error)
     return config_stream