예제 #1
0
class Sensor(Device):
    delay_validator = validators.DecimalValidator(name='delay', min_value=0.2)
    max_delay_validator = validators.DecimalValidator(name='max_delay')
    config_mode_validator = validators.BooleanValidator(name='config_mode')

    def __init__(self, delay=10, max_delay=0, config_mode=False, **kwargs):
        super().__init__(**kwargs)
        self.delay = self.delay_validator(delay)
        self.max_delay = self.max_delay_validator(max_delay)
        self.config_mode = self.config_mode_validator(config_mode)
        self.sensor_previous_value = None
        self.sensor_set_state_time = 0

    async def setup(self):
        self.set_state('delay', self.delay)
        self.set_state('max_delay', self.max_delay)
        self.set_state('config_mode', json.dumps(self.config_mode))

    async def loop(self):
        while True:
            await self.set_value()
            await asyncio.sleep(float(self.delay))

    async def message_received(self, sender=None, topic=None, payload=None):
        if self.config_mode and bool(payload):
            if topic == 'delay':
                self.delay = self.delay_validator(payload)
                self.set_state('delay', self.delay)
            if topic == 'max_delay':
                self.max_delay = self.max_delay_validator(payload)
                self.set_state('max_delay', self.max_delay)

    async def set_value(self):
        value = await self.get_value()
        value = self.clean_value(value)
        if self.is_changed(value, self.sensor_previous_value):
            self.sensor_set_state_time = time.time_ns()
            self.set_state('value', value)
        else:
            now = time.time_ns()
            if (now - self.sensor_set_state_time
                ) // 1000000000 >= self.max_delay:
                self.sensor_set_state_time = time.time_ns()
                self.set_state('value', value)
        self.sensor_previous_value = value

    async def get_value(self):
        raise NotImplementedError()

    def clean_value(self, value):
        return value

    def is_changed(self, value, previous_value):
        return not (value == previous_value)
예제 #2
0
 def test_min_value(self):
     validator = validators.DecimalValidator(name='delay', min_value=2)
     self.assertEqual(validator(2), Decimal('2'))
     with self.assertRaises(ValidationError) as ctx:
         validator(1.99)
     self.assertEqual(ctx.exception.message,
                      'Ensure delay is greater than or equal to 2.000000')
     validator = validators.DecimalValidator(name='delay', min_value=0.2)
     self.assertEqual(validator(0.2), Decimal('0.2'))
     with self.assertRaises(ValidationError) as ctx:
         validator(0.199)
     self.assertEqual(ctx.exception.message,
                      'Ensure delay is greater than or equal to 0.200000')
예제 #3
0
 def __init__(self,
              scale=1,
              precision=0,
              change_margin=0,
              unit_of_measurement='',
              **kwargs):
     super().__init__(**kwargs)
     self.scale = self.scale_validator(scale)
     self.precision = self.precision_validator(precision)
     self.change_margin_validator = validators.DecimalValidator(
         name='change_margin', precision=self.precision)
     self.change_margin = self.change_margin_validator(change_margin)
     self.unit_of_measurement = unit_of_measurement
     self.value_validator = validators.DecimalValidator(
         name='value', precision=self.precision)
예제 #4
0
 def test_max_value(self):
     validator = validators.DecimalValidator(name='delay', max_value=2)
     self.assertEqual(validator(2), Decimal('2'))
     with self.assertRaises(ValidationError) as ctx:
         validator(2.01)
     self.assertEqual(ctx.exception.message,
                      'Ensure delay is less than or equal to 2.000000')
예제 #5
0
 def test_precision(self):
     validator = validators.DecimalValidator(name='delay', precision=2)
     self.assertEqual(validator(1.2), Decimal('1.2'))
     self.assertEqual(validator(1.23), Decimal('1.23'))
     self.assertEqual(validator(1.234), Decimal('1.23'))
     validator = validators.DecimalValidator(name='delay', precision=0)
     self.assertEqual(validator(-0.125), Decimal('0'))
     self.assertEqual(validator(Decimal('-0.125')), Decimal('0'))
     self.assertEqual(str(validator(-0.125)), '0')
     self.assertEqual(str(validator('-0.125')), '0')
     self.assertEqual(str(validator(Decimal('-0.125'))), '0')
     self.assertEqual(validator(54321.2), Decimal('54321'))
     self.assertEqual(validator(54321.23), Decimal('54321'))
     self.assertEqual(validator(54321.234), Decimal('54321'))
     validator = validators.DecimalValidator(name='delay', precision=-2)
     self.assertEqual(validator(1550), Decimal('1600'))
     self.assertEqual(validator(54321.2), Decimal('54300'))
     self.assertEqual(validator(54321.23), Decimal('54300'))
     self.assertEqual(validator(54321.234), Decimal('54300'))
예제 #6
0
class NumericSensor(Sensor):
    scale_validator = validators.DecimalValidator(name='scale')
    precision_validator = validators.IntegerValidator(name='precision')

    def __init__(self,
                 scale=1,
                 precision=0,
                 change_margin=0,
                 unit_of_measurement='',
                 **kwargs):
        super().__init__(**kwargs)
        self.scale = self.scale_validator(scale)
        self.precision = self.precision_validator(precision)
        self.change_margin_validator = validators.DecimalValidator(
            name='change_margin', precision=self.precision)
        self.change_margin = self.change_margin_validator(change_margin)
        self.unit_of_measurement = unit_of_measurement
        self.value_validator = validators.DecimalValidator(
            name='value', precision=self.precision)

    async def setup(self):
        await super().setup()
        self.set_state('scale', self.scale)
        self.set_state('precision', self.precision)
        self.set_state('change_margin', self.change_margin)
        self.set_state('unit_of_measurement', self.unit_of_measurement)

    def clean_value(self, value):
        return self.value_validator(Decimal(value) * self.scale)

    def is_changed(self, value, previous_value):
        if previous_value is None:
            return True
        if self.change_margin == 0:
            return not (value == previous_value)
        return bool(abs(value - previous_value) >= self.change_margin)

    async def message_received(self, sender=None, topic=None, payload=None):
        await super().message_received(sender=sender,
                                       topic=topic,
                                       payload=payload)
        if self.config_mode and bool(payload):
            if topic == 'scale':
                self.scale = self.scale_validator(payload)
                self.set_state('scale', self.scale)
            if topic == 'precision':
                self.precision = self.precision_validator(payload)
                self.set_state('precision', self.precision)
            if topic == 'change_margin':
                self.change_margin = self.change_margin_validator(payload)
                self.set_state('change_margin', self.change_margin)
예제 #7
0
 def test_simple(self):
     validator = validators.DecimalValidator(name='delay')
     self.assertEqual(validator(0), Decimal('0'))
     self.assertEqual(validator(-0), Decimal('0'))
     self.assertEqual(validator(0.1), Decimal('0.1'))
     self.assertEqual(validator(1), Decimal('1'))
     self.assertEqual(validator(1.2), Decimal('1.2'))
     self.assertEqual(validator(-1.2), Decimal('-1.2'))
     self.assertEqual(validator('0'), Decimal('0'))
     self.assertEqual(validator('-0'), Decimal('0'))
     self.assertEqual(validator('0.1'), Decimal('0.1'))
     self.assertEqual(validator('1'), Decimal('1'))
     self.assertEqual(validator('1.2'), Decimal('1.2'))
     self.assertEqual(validator('-1.2'), Decimal('-1.2'))
     self.assertEqual(validator(Decimal('0')), Decimal('0'))
     self.assertEqual(validator(Decimal('-0')), Decimal('0'))
     self.assertEqual(validator(Decimal('-0.0000001')), Decimal('0'))
     self.assertEqual(validator(Decimal('-0.000001')), Decimal('-0.000001'))
     self.assertEqual(validator(Decimal('0.1')), Decimal('0.1'))
     self.assertEqual(validator(Decimal('-1.2')), Decimal('-1.2'))
     with self.assertRaises(ValidationError) as ctx:
         validator('text')
     self.assertEqual(ctx.exception.message, 'Ensure delay is a number.')