def test_has_group_address(self): """Test expose sensor has group address.""" xknx = XKNX() expose_sensor = ExposeSensor( xknx, "TestSensor", value_type="temperature", group_address="1/2/3" ) self.assertTrue(expose_sensor.has_group_address(GroupAddress("1/2/3"))) self.assertFalse(expose_sensor.has_group_address(GroupAddress("1/2/4")))
def test_state_addresses(self): """Test expose sensor returns empty list as state addresses.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', value_type='temperature', group_address='1/2/3') self.assertEqual(expose_sensor.state_addresses(), [])
def test_str_binary(self): """Test resolve state with binary sensor.""" xknx = XKNX() expose_sensor = ExposeSensor( xknx, "TestSensor", group_address="1/2/3", value_type="binary" ) expose_sensor.sensor_value.payload = DPTBinary(1) self.assertEqual(expose_sensor.resolve_state(), True) self.assertEqual(expose_sensor.unit_of_measurement(), None)
def test_str_percent(self): """Test resolve state with percent sensor.""" xknx = XKNX() expose_sensor = ExposeSensor( xknx, "TestSensor", group_address="1/2/3", value_type="percent" ) expose_sensor.sensor_value.payload = DPTArray((0x40,)) self.assertEqual(expose_sensor.resolve_state(), 25) self.assertEqual(expose_sensor.unit_of_measurement(), "%")
def test_has_group_address(self): """Test expose sensor has group address.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', value_type='temperature', group_address='1/2/3') self.assertTrue(expose_sensor.has_group_address(GroupAddress('1/2/3'))) self.assertFalse(expose_sensor.has_group_address(GroupAddress('1/2/4')))
def test_str_temperature(self): """Test resolve state with temperature sensor.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', group_address='1/2/3', value_type="temperature") expose_sensor.sensor_value.payload = DPTArray((0x0c, 0x1a)) self.assertEqual(expose_sensor.resolve_state(), 21.0) self.assertEqual(expose_sensor.unit_of_measurement(), "°C")
def test_str_percent(self): """Test resolve state with percent sensor.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', group_address='1/2/3', value_type="percent") expose_sensor.sensor_value.payload = DPTArray((0x40,)) self.assertEqual(expose_sensor.resolve_state(), 25) self.assertEqual(expose_sensor.unit_of_measurement(), "%")
def test_str_binary(self): """Test resolve state with binary sensor.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', group_address='1/2/3', value_type="binary") expose_sensor.sensor_value.payload = DPTBinary(1) self.assertEqual(expose_sensor.resolve_state(), True) self.assertEqual(expose_sensor.unit_of_measurement(), None)
def test_expose_sensor(self): """Test string representation of expose sensor object.""" xknx = XKNX(loop=self.loop) sensor = ExposeSensor( xknx, name='MeinSensor', group_address='1/2/3', value_type='percent') self.assertEqual( str(sensor), '<ExposeSensor name="MeinSensor" sensor="GroupAddress("1/2/3")/None/None/None" value="None" unit="%"/>') self.loop.run_until_complete(asyncio.Task(sensor.set(25))) self.assertEqual( str(sensor), '<ExposeSensor name="MeinSensor" sensor="GroupAddress("1/2/3")/None/<DPTArray value="[0x40]" />/25" value="25" unit="%"/>')
def test_expose_sensor(self): """Test string representation of expose sensor object.""" xknx = XKNX(loop=self.loop) sensor = ExposeSensor( xknx, name='MeinSensor', group_address='1/2/3', value_type='percent') self.assertEqual( str(sensor), '<ExposeSensor name="MeinSensor" sensor="GroupAddress("1/2/3")/None/None/None" value="None" unit="%"/>') self.loop.run_until_complete(asyncio.Task(sensor.set(25))) self.assertEqual( str(sensor), '<ExposeSensor name="MeinSensor" sensor="GroupAddress("1/2/3")/None/<DPTArray value="[0x40]" />/25" value="25" unit="%"/>')
def test_set_temperature(self): """Test set with temperature sensor.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', group_address='1/2/3', value_type="temperature") self.loop.run_until_complete(asyncio.Task(expose_sensor.set(21.0))) self.assertEqual(xknx.telegrams.qsize(), 1) telegram = xknx.telegrams.get_nowait() self.assertEqual( telegram, Telegram( GroupAddress('1/2/3'), TelegramType.GROUP_WRITE, payload=DPTArray((0x0c, 0x1a))))
def test_set_percent(self): """Test set with percent sensor.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor(xknx, 'TestSensor', group_address='1/2/3', value_type="percent") self.loop.run_until_complete(asyncio.Task(expose_sensor.set(75))) self.assertEqual(xknx.telegrams.qsize(), 1) telegram = xknx.telegrams.get_nowait() print(telegram) self.assertEqual( telegram, Telegram(GroupAddress('1/2/3'), TelegramType.GROUP_WRITE, payload=DPTArray((0x40, ))))
def parse_group_expose_sensor(self, entries): """Parse a exposed sensor section of xknx.yaml.""" for entry in entries: expose_sensor = ExposeSensor.from_config( self.xknx, entry, entries[entry]) self.xknx.devices.add(expose_sensor)
def test_set_binary(self): """Test set with binary sensor.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', group_address='1/2/3', value_type="binary") self.loop.run_until_complete(asyncio.Task(expose_sensor.set(False))) self.assertEqual(xknx.telegrams.qsize(), 1) telegram = xknx.telegrams.get_nowait() self.assertEqual( telegram, Telegram( GroupAddress('1/2/3'), TelegramType.GROUP_WRITE, payload=DPTBinary(0)))
def test_process_callback(self): """Test setting value. Test if callback is called.""" # pylint: disable=no-self-use xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', group_address='1/2/3', value_type="temperature") after_update_callback = Mock() async def async_after_update_callback(device): """Async callback.""" after_update_callback(device) expose_sensor.register_device_updated_cb(async_after_update_callback) self.loop.run_until_complete(asyncio.Task(expose_sensor.set(21.0))) after_update_callback.assert_called_with(expose_sensor)
def test_process_callback(self): """Test setting value. Test if callback is called.""" # pylint: disable=no-self-use xknx = XKNX() expose_sensor = ExposeSensor( xknx, "TestSensor", group_address="1/2/3", value_type="temperature" ) after_update_callback = Mock() async def async_after_update_callback(device): """Async callback.""" after_update_callback(device) expose_sensor.register_device_updated_cb(async_after_update_callback) self.loop.run_until_complete(expose_sensor.set(21.0)) self.loop.run_until_complete(xknx.devices.process(xknx.telegrams.get_nowait())) after_update_callback.assert_called_with(expose_sensor)
def test_set_percent(self): """Test set with percent sensor.""" xknx = XKNX() expose_sensor = ExposeSensor(xknx, "TestSensor", group_address="1/2/3", value_type="percent") self.loop.run_until_complete(expose_sensor.set(75)) self.assertEqual(xknx.telegrams.qsize(), 1) telegram = xknx.telegrams.get_nowait() self.assertEqual( telegram, Telegram( GroupAddress("1/2/3"), TelegramType.GROUP_WRITE, payload=DPTArray((0xBF, )), ), )
def test_process_temperature(self): """Test reading temperature expose sensor from bus.""" xknx = XKNX() expose_sensor = ExposeSensor( xknx, "TestSensor", value_type="temperature", group_address="1/2/3" ) expose_sensor.sensor_value.payload = DPTArray((0x0C, 0x1A)) telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead()) self.loop.run_until_complete(expose_sensor.process(telegram)) self.assertEqual(xknx.telegrams.qsize(), 1) telegram = xknx.telegrams.get_nowait() self.assertEqual( telegram, Telegram( destination_address=GroupAddress("1/2/3"), payload=GroupValueResponse(DPTArray((0x0C, 0x1A))), ), )
def test_config_expose_sensor(self): """Test reading ExposeSensor from config file.""" xknx = XKNX(config='xknx.yaml', loop=self.loop) self.assertEqual( xknx.devices['Outside.Temperature'], ExposeSensor(xknx, 'Outside.Temperature', group_address='2/0/3', value_type='temperature', device_updated_cb=xknx.devices.device_updated))
def test_binary_sensor_loop(self): """Test binary_sensor and expose_sensor with binary values.""" test_cases = [ ("binary", DPTBinary(0), False), ("binary", DPTBinary(1), True), ] for value_type, test_payload, test_value in test_cases: with self.subTest(value_type=value_type): xknx = XKNX(loop=self.loop) sensor = BinarySensor( xknx, "TestSensor_%s" % value_type, group_address_state="1/1/1" ) expose = ExposeSensor( xknx, "TestExpose_%s" % value_type, group_address="2/2/2", value_type=value_type, ) incoming_telegram = Telegram( GroupAddress("1/1/1"), TelegramType.GROUP_WRITE, direction=TelegramDirection.INCOMING, payload=test_payload, ) self.loop.run_until_complete(sensor.process(incoming_telegram)) incoming_value = sensor.is_on() self.assertEqual(incoming_value, test_value) self.loop.run_until_complete(expose.set(test_value)) self.assertEqual(xknx.telegrams.qsize(), 1) outgoing_telegram = xknx.telegrams.get_nowait() self.assertEqual( outgoing_telegram, Telegram( GroupAddress("2/2/2"), TelegramType.GROUP_WRITE, direction=TelegramDirection.OUTGOING, payload=test_payload, ), )
def test_process_temperature(self): """Test reading temperature expose sensor from bus.""" xknx = XKNX(loop=self.loop) expose_sensor = ExposeSensor( xknx, 'TestSensor', value_type='temperature', group_address='1/2/3') expose_sensor.sensor_value.payload = DPTArray((0x0c, 0x1a)) telegram = Telegram(GroupAddress('1/2/3')) telegram.telegramtype = TelegramType.GROUP_READ self.loop.run_until_complete(asyncio.Task(expose_sensor.process(telegram))) self.assertEqual(xknx.telegrams.qsize(), 1) telegram = xknx.telegrams.get_nowait() self.assertEqual( telegram, Telegram( GroupAddress('1/2/3'), TelegramType.GROUP_RESPONSE, payload=DPTArray((0x0c, 0x1a))))
def test_binary_sensor_loop(self): """Test binary_sensor and expose_sensor with binary values.""" test_cases = [ ('binary', DPTBinary(0), False), ('binary', DPTBinary(1), True), ] for value_type, test_payload, test_value in test_cases: with self.subTest(value_type=value_type): xknx = XKNX(loop=self.loop) sensor = BinarySensor( xknx, 'TestSensor_%s' % value_type, group_address_state='1/1/1' ) expose = ExposeSensor( xknx, 'TestExpose_%s' % value_type, group_address='2/2/2', value_type=value_type ) incoming_telegram = Telegram(GroupAddress('1/1/1'), TelegramType.GROUP_WRITE, direction=TelegramDirection.INCOMING, payload=test_payload) self.loop.run_until_complete(asyncio.Task(sensor.process(incoming_telegram))) incoming_value = sensor.is_on() self.assertEqual(incoming_value, test_value) self.loop.run_until_complete(asyncio.Task(expose.set(test_value))) self.assertEqual(xknx.telegrams.qsize(), 1) outgoing_telegram = xknx.telegrams.get_nowait() self.assertEqual( outgoing_telegram, Telegram( GroupAddress('2/2/2'), TelegramType.GROUP_WRITE, direction=TelegramDirection.OUTGOING, payload=test_payload))
def test_process_percent(self): """Test reading percent expose sensor from bus.""" xknx = XKNX() expose_sensor = ExposeSensor(xknx, "TestSensor", value_type="percent", group_address="1/2/3") expose_sensor.sensor_value.payload = DPTArray((0x40, )) telegram = Telegram(GroupAddress("1/2/3")) telegram.telegramtype = TelegramType.GROUP_READ self.loop.run_until_complete(expose_sensor.process(telegram)) self.assertEqual(xknx.telegrams.qsize(), 1) telegram = xknx.telegrams.get_nowait() self.assertEqual( telegram, Telegram( GroupAddress("1/2/3"), TelegramType.GROUP_RESPONSE, payload=DPTArray((0x40, )), ), )
def test_array_sensor_loop(self): """Test sensor and expose_sensor with different values.""" test_cases = [ ('angle', DPTArray((0x0B)), 16), ('brightness', DPTArray((0x27, 0x10)), 10000), ('color_temperature', DPTArray((0x0D, 0x48)), 3400), ('counter_pulses', DPTArray((0x9F)), -97), ('current', DPTArray((0x00, 0x03)), 3), ('electric_current', DPTArray((0x3D, 0xCC, 0xCC, 0xCD)), 0.1), ('electric_potential', DPTArray((0x43, 0xF0, 0xDE, 0xB8)), 481.74), ('energy', DPTArray((0x43, 0xE4, 0x00, 0x00)), 456), ('enthalpy', DPTArray((0xC1, 0x4E)), -4387.84), ('frequency', DPTArray((0x42, 0x46, 0xCC, 0xCD)), 49.7), ('heatflowrate', DPTArray((0x42, 0xAE, 0x00, 0x00)), 87), ('humidity', DPTArray((0x6C, 0xB6)), 98795.52), ('illuminance', DPTArray((0x2F, 0xE9)), 648), ('luminous_flux', DPTArray((0x43, 0x87, 0x40, 0x00)), 270.5), ('percent', DPTArray((0x26)), 15), ('percentU8', DPTArray((0xCD)), 205), ('percentV8', DPTArray((0x9A)), -102), ('phaseanglerad', DPTArray((0xC1, 0x10, 0x00, 0x00)), -9), ('phaseangledeg', DPTArray((0x43, 0x87, 0x40, 0x00)), 270.5), ('power', DPTArray((0x42, 0xA9, 0xBD, 0x71)), 84.87), ('powerfactor', DPTArray((0x42, 0xA9, 0x6B, 0x85)), 84.71), ('ppm', DPTArray((0x00, 0x03)), 0.03), ('pressure', DPTArray((0x42, 0xA9, 0x6B, 0x85)), 84.71), ('pulse', DPTArray((0x11)), 17), ('scene_number', DPTArray((0x00)), 1), ('speed', DPTArray((0x00, 0x00, 0x00, 0x00)), 0), ('speed_ms', DPTArray((0x0E, 0xA4)), 34), ('string', DPTArray((0x4B, 0x4E, 0x58, 0x20, 0x69, 0x73, 0x20, 0x4F, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00)), "KNX is OK"), ('temperature', DPTArray((0x03, 0x12)), 7.86), ('voltage', DPTArray((0x07, 0x9A)), 19.46), # Generic DPT Without Min/Max and Unit. ('DPT-5', DPTArray((0x1F)), 31), ('1byte_unsigned', DPTArray((0x08)), 8), ('DPT-7', DPTArray((0xD4, 0x31)), 54321), ('2byte_unsigned', DPTArray((0x30, 0x39)), 12345), ('DPT-9', DPTArray((0x2E, 0xA9)), 545.6), ('DPT-12', DPTArray((0x07, 0x5B, 0xCD, 0x15)), 123456789), ('4byte_unsigned', DPTArray((0x00, 0x00, 0x00, 0x00)), 0), ('DPT-13', DPTArray((0x02, 0xE5, 0x5E, 0xF7)), 48586487), ('4byte_signed', DPTArray((0xFD, 0x1A, 0xA1, 0x09)), -48586487), ('DPT-14', DPTArray((0x47, 0xC0, 0xF7, 0x20)), 98798.25), ('4byte_float', DPTArray((0xC2, 0x09, 0xEE, 0xCC)), -34.4832), ] for value_type, test_payload, test_value in test_cases: with self.subTest(value_type=value_type): xknx = XKNX(loop=self.loop) sensor = Sensor( xknx, 'TestSensor_%s' % value_type, group_address_state='1/1/1', value_type=value_type ) expose = ExposeSensor( xknx, 'TestExpose_%s' % value_type, group_address='2/2/2', value_type=value_type ) incoming_telegram = Telegram(GroupAddress('1/1/1'), TelegramType.GROUP_WRITE, direction=TelegramDirection.INCOMING, payload=test_payload) self.loop.run_until_complete(asyncio.Task(sensor.process(incoming_telegram))) incoming_value = sensor.resolve_state() if isinstance(test_value, float): self.assertEqual(round(incoming_value, 4), test_value) else: self.assertEqual(incoming_value, test_value) # HA sends strings for new values stringified_value = str(test_value) self.loop.run_until_complete(asyncio.Task(expose.set(stringified_value))) self.assertEqual(xknx.telegrams.qsize(), 1) outgoing_telegram = xknx.telegrams.get_nowait() self.assertEqual( outgoing_telegram, Telegram( GroupAddress('2/2/2'), TelegramType.GROUP_WRITE, direction=TelegramDirection.OUTGOING, payload=test_payload))