def test_function_filter(self): """Verify the function filter class """ s = ValueListSensor(1, value_stream) st = SensorAsOutputThing(s) captured_list_ref = [[]] got_completed_ref = [ False, ] def on_next(self, x): captured_list_ref[0].append(x.val) self._dispatch_next(x) def on_completed(self): got_completed_ref[0] = True self._dispatch_completed() ff = FunctionFilter(st, on_next=on_next, on_completed=on_completed) vo = ValidationInputThing(value_stream, self.test_function_filter) ff.connect(vo) st.print_downstream() scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(st, 0.5) # sample twice every second scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") self.assertEqual(value_stream, captured_list_ref[0]) self.assertTrue(got_completed_ref[0]) print("That's all folks")
def test_function_filter_error_handling(self): """Verify the error handling functionality of the function filter. We do this by connecting two downstream paths to the sensor. The first includes a function filter that throws an error when it encouters a sensor reading of 120. This should disconnect th stream at this point. The second is a normal validation input thing. It is connected directly to the sensor, and thus should not see any errors. """ s = ValueListSensor(1, value_stream) st = SensorAsOutputThing(s) captured_list_ref = [[]] got_completed_ref = [ False, ] got_on_error_ref = [ False, ] def on_next_throw_exc(self, x): if x.val == 120: raise Exception("expected exc") else: captured_list_ref[0].append(x.val) self._dispatch_next(x) def on_completed(self): got_completed_ref[0] = True self._dispatch_completed() def on_error(self, e): got_on_error_ref[0] = True self._dispatch_error(e) ff = FunctionFilter(st, on_next=on_next_throw_exc, on_completed=on_completed, on_error=on_error) ct = CaptureInputThing(expecting_error=True) ff.map(lambda x: x.val).connect(ct) vo = ValidationInputThing(value_stream, self.test_function_filter_error_handling) st.connect(vo) st.print_downstream() scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(st, 0.5) # sample twice every second scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") self.assertFalse(ct.completed, "Capture thing should not have completed") self.assertTrue(ct.errored, "Capture thing should have seen an error") self.assertFalse(got_completed_ref[0]) self.assertTrue(got_on_error_ref[0]) self.assertEqual([20, 30, 100], ct.events, "Capture thing event mismatch") self.assertEqual([20, 30, 100], captured_list_ref[0], "captured_list_ref mismatch") print("That's all folks")
def setup(threshold=25): lux = SensorAsOutputThing(LuxSensor()) lux.connect(print) lux.csv_writer(os.path.expanduser('~/lux.csv')) led = GpioPinOut() actions = lux.map(lambda event: event.val > threshold) actions.connect(led) actions.connect(lambda v: print('ON' if v else 'OFF')) lux.print_downstream() return (lux, led)
def setup(broker, threshold): lux = SensorAsOutputThing(LuxSensor()) lux.connect(print) led = GpioPinOut() actions = lux.map(lambda event: event.val > threshold) actions.connect(led) actions.connect(lambda v: print('ON' if v else 'OFF')) lux.to_json().connect(MQTTWriter(broker, topics=[('bogus/bogus', 0)])) lux.print_downstream() return (lux, led)
def test_where(self): """In this version, we create a publisher and use method chaining to compose the filters""" s = ValueListSensor(1, value_stream) p = SensorAsOutputThing(s) w = p.where(predicate) w.output() vo = ValidationInputThing(expected_stream, self.test_where) w.connect(vo) scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(p, 0.5) # sample twice every second p.print_downstream() scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") print("That's all folks")
def run_example(): sensor = SensorAsOutputThing(DummyTempSensor('temp-1', input_sequence)) sensor.output() # let us see the raw values dispatcher = sensor.transduce(RunningAvg(4))\ .passthrough(lambda evt: print("Running avg temp: %s" % round(evt.val, 2))) \ .dispatch([(lambda v: v[2]>=T_high, 't_high'), (lambda v: v[2]<=T_low, 't_low')]) controller = Controller() dispatcher.connect(controller, port_mapping=('t_high', 't_high')) dispatcher.connect(controller, port_mapping=('t_low', 't_low')) dispatcher.connect(controller, port_mapping=('default', 'between')) controller.connect(BypassValveActuator()) sensor.print_downstream() scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(sensor, 0.5) scheduler.run_forever() print("got to the end")
print("LED Completed") def __str__(self): return 'LED' # instantiate an LED led = LED() # Now, build a pipeline to sample events returned from the sensor, # convert to a boolean based on whether the value is greater than # the mean, and output to the LED. import thingflow.filters.map sensor.map(lambda evt: evt.val > MEAN).connect(led) # If you want to see the raw value of each sensor, just add the output() element import thingflow.filters.output sensor.output() # Call a debug method on the base output_thing class to see the element tree rooted # at sensor. sensor.print_downstream() # Now, we need to schedule the sensor to be sampled import asyncio from thingflow.base import Scheduler scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(sensor, 1.0) # sample once a second scheduler.run_forever() # run until all sensors complete print("That's all folks!")