def to_knx(self, value): """Convert value to payload.""" if value == self.Direction.INCREASE: return DPTBinary(1) if self.invert else DPTBinary(0) if value == self.Direction.DECREASE: return DPTBinary(0) if self.invert else DPTBinary(1) raise ConversionError("value invalid", value=value, device_name=self.device_name)
def from_knx(self, payload): """Convert current payload to value.""" if payload == DPTBinary(0): return self.Direction.DECREASE if self.invert else self.Direction.INCREASE if payload == DPTBinary(1): return self.Direction.INCREASE if self.invert else self.Direction.DECREASE raise CouldNotParseTelegram("payload invalid", payload=payload, device_name=self.device_name)
def test_value_reader_telegram_received(self): """Test value reader: telegram_received.""" xknx = XKNX(loop=self.loop) test_group_address = GroupAddress("0/0/0") expected_telegram_1 = Telegram(group_address=test_group_address, telegramtype=TelegramType.GROUP_RESPONSE, direction=TelegramDirection.INCOMING, payload=DPTBinary(1)) expected_telegram_2 = Telegram(group_address=test_group_address, telegramtype=TelegramType.GROUP_WRITE, direction=TelegramDirection.INCOMING, payload=DPTBinary(1)) telegram_wrong_address = Telegram(group_address=GroupAddress("0/0/1"), telegramtype=TelegramType.GROUP_RESPONSE, direction=TelegramDirection.INCOMING, payload=DPTBinary(1)) telegram_wrong_type = Telegram(group_address=test_group_address, telegramtype=TelegramType.GROUP_READ, direction=TelegramDirection.INCOMING, payload=DPTBinary(1)) value_reader = ValueReader(xknx, test_group_address) def async_telegram_received(test_telegram): return self.loop.run_until_complete(value_reader.telegram_received(test_telegram)) self.assertFalse(async_telegram_received(telegram_wrong_address)) self.assertFalse(async_telegram_received(telegram_wrong_type)) self.assertIsNone(value_reader.received_telegram) self.assertTrue(async_telegram_received(expected_telegram_1)) self.assertEqual(value_reader.received_telegram, expected_telegram_1) self.assertTrue(async_telegram_received(expected_telegram_2)) self.assertEqual(value_reader.received_telegram, expected_telegram_2)
def from_knx(self, payload): """Convert current payload to value.""" if payload == DPTBinary(0): return self.Value.ON if self.invert else self.Value.OFF elif payload == DPTBinary(1): return self.Value.OFF if self.invert else self.Value.ON raise ConversionError(payload)
def test_process_significant_bit(self): """Test process / reading telegrams from telegram queue with specific significant bit set.""" xknx = XKNX(loop=self.loop) binaryinput = BinarySensor(xknx, 'TestInput', '1/2/3', significant_bit=3) self.assertEqual(binaryinput.state, BinarySensorState.OFF) # Wrong significant bit: 0000 1011 = 11 telegram_on = Telegram() telegram_on.payload = DPTBinary(11) self.loop.run_until_complete( asyncio.Task(binaryinput.process(telegram_on))) self.assertEqual(binaryinput.state, BinarySensorState.OFF) # Correct significant bit: 0000 1101 = 13 telegram_on = Telegram() telegram_on.payload = DPTBinary(13) self.loop.run_until_complete( asyncio.Task(binaryinput.process(telegram_on))) self.assertEqual(binaryinput.state, BinarySensorState.ON) # Resetting, significant bit: 0000 0011 = 3 telegram_off = Telegram() telegram_off.payload = DPTBinary(3) self.loop.run_until_complete( asyncio.Task(binaryinput.process(telegram_off))) self.assertEqual(binaryinput.state, BinarySensorState.OFF)
def build_and_destroy_tunnel(xknx): gatewayscanner = GatewayScanner(xknx) yield from gatewayscanner.async_start() if not gatewayscanner.found: print("No Gateways found") return src_address = Address("15.15.249") print("Connecting to {}:{} from {}".format(gatewayscanner.found_ip_addr, gatewayscanner.found_port, gatewayscanner.found_local_ip)) tunnel = Tunnel(xknx, src_address, local_ip=gatewayscanner.found_local_ip, gateway_ip=gatewayscanner.found_ip_addr, gateway_port=gatewayscanner.found_port) yield from tunnel.connect_udp() yield from tunnel.connect() yield from tunnel.send_telegram( Telegram(Address('1/0/15'), payload=DPTBinary(0))) yield from asyncio.sleep(2) yield from tunnel.send_telegram( Telegram(Address('1/0/15'), payload=DPTBinary(1))) yield from asyncio.sleep(2) yield from tunnel.connectionstate() yield from tunnel.disconnect()
def test_compare_binary(self): """Test comparison of DPTBinary objects.""" self.assertEqual(DPTBinary(0), DPTBinary(0)) self.assertEqual(DPTBinary(2), DPTBinary(2)) self.assertNotEqual(DPTBinary(1), DPTBinary(4)) self.assertNotEqual(DPTBinary(2), DPTBinary(0)) self.assertNotEqual(DPTBinary(0), DPTBinary(2))
async def main(): """Connect to a tunnel, send 2 telegrams and disconnect.""" xknx = XKNX() gatewayscanner = GatewayScanner(xknx) await gatewayscanner.start() if not gatewayscanner.found: print("No Gateways found") return src_address = Address("15.15.249") print("Connecting to {}:{} from {}".format(gatewayscanner.found_ip_addr, gatewayscanner.found_port, gatewayscanner.found_local_ip)) tunnel = Tunnel(xknx, src_address, local_ip=gatewayscanner.found_local_ip, gateway_ip=gatewayscanner.found_ip_addr, gateway_port=gatewayscanner.found_port) await tunnel.connect_udp() await tunnel.connect() await tunnel.send_telegram( Telegram(Address('1/0/15'), payload=DPTBinary(1))) await asyncio.sleep(2) await tunnel.send_telegram( Telegram(Address('1/0/15'), payload=DPTBinary(0))) await asyncio.sleep(2) await tunnel.connectionstate() await tunnel.disconnect()
def test_power_on_off(self): """Test turn_on and turn_off functions.""" xknx = XKNX(loop=self.loop) climate = Climate(xknx, 'TestClimate', group_address_on_off='1/2/2') self.loop.run_until_complete(asyncio.Task(climate.turn_on())) self.assertEqual(climate.is_on, True) self.assertEqual( xknx.telegrams.get_nowait(), Telegram(GroupAddress('1/2/2'), payload=DPTBinary(True))) self.loop.run_until_complete(asyncio.Task(climate.turn_off())) self.assertEqual(climate.is_on, False) self.assertEqual( xknx.telegrams.get_nowait(), Telegram(GroupAddress('1/2/2'), payload=DPTBinary(False))) climate_inv = Climate(xknx, 'TestClimate', group_address_on_off='1/2/2', on_off_invert=True) self.loop.run_until_complete(asyncio.Task(climate_inv.turn_on())) self.assertEqual(climate_inv.is_on, True) self.assertEqual( xknx.telegrams.get_nowait(), Telegram(GroupAddress('1/2/2'), payload=DPTBinary(False))) self.loop.run_until_complete(asyncio.Task(climate_inv.turn_off())) self.assertEqual(climate_inv.is_on, False) self.assertEqual( xknx.telegrams.get_nowait(), Telegram(GroupAddress('1/2/2'), payload=DPTBinary(True)))
def to_knx(self, value): """Convert value to payload.""" if value == self.Direction.INCREASE: return DPTBinary(1) if self.invert else DPTBinary(0) elif value == self.Direction.DECREASE: return DPTBinary(0) if self.invert else DPTBinary(1) raise ConversionError(value)
def to_knx(self, value): """Convert value to payload.""" if value == self.Value.OFF: return DPTBinary(1) if self.invert else DPTBinary(0) elif value == self.Value.ON: return DPTBinary(0) if self.invert else DPTBinary(1) raise ConversionError(value)
async def set_operation_mode(self, operation_mode): """Set the operation mode of a thermostat. Send new operation_mode to BUS and update internal state.""" if not self.supports_operation_mode: raise DeviceIllegalValue("operation mode not supported", operation_mode) if self.group_address_operation_mode is not None: await self.send(self.group_address_operation_mode, DPTArray(DPTHVACMode.to_knx(operation_mode))) if self.group_address_operation_mode_protection is not None: protection_mode = operation_mode == HVACOperationMode.FROST_PROTECTION await self.send(self.group_address_operation_mode_protection, DPTBinary(protection_mode)) if self.group_address_operation_mode_night is not None: night_mode = operation_mode == HVACOperationMode.NIGHT await self.send(self.group_address_operation_mode_night, DPTBinary(night_mode)) if self.group_address_operation_mode_comfort is not None: comfort_mode = operation_mode == HVACOperationMode.COMFORT await self.send(self.group_address_operation_mode_comfort, DPTBinary(comfort_mode)) if self.group_address_controller_status is not None: await self.send( self.group_address_controller_status, DPTArray(DPTControllerStatus.to_knx(operation_mode))) if self.group_address_controller_mode is not None: await self.send(self.group_address_controller_mode, DPTArray(DPTHVACContrMode.to_knx(operation_mode))) await self._set_internal_operation_mode(operation_mode)
def test_binary(self): xknx = XKNX(self.loop, start=False) sensor = Sensor(xknx, 'DiningRoom.Motion.Sensor', group_address='3/0/1', value_type='binary', sensor_class='motion') self.assertEqual(sensor.significant_bit, 1) self.assertTrue(sensor.is_binary()) # No sensor set, binary_state should resolve to False self.assertFalse(sensor.binary_state()) # First bit is set sensor.state = DPTBinary(5) self.assertTrue(sensor.binary_state()) # State with the wrong bit set sensor.state = DPTBinary(8) self.assertFalse(sensor.binary_state()) # Shifting significant bit to 4th position sensor.significant_bit = 4 sensor.state = DPTBinary(8) self.assertTrue(sensor.binary_state()) sensor.state = DPTBinary(7) self.assertFalse(sensor.binary_state())
def from_knx(self, payload): """Convert current payload to value.""" if payload == DPTBinary(0): return self.invert if payload == DPTBinary(1): return not self.invert raise CouldNotParseTelegram("payload invalid", payload=payload, device_name=self.device_name)
def test_connect_request(self): """Test parsing and streaming connection tunneling request KNX/IP packet.""" raw = ((0x06, 0x10, 0x04, 0x20, 0x00, 0x15, 0x04, 0x01, 0x17, 0x00, 0x11, 0x00, 0xbc, 0xe0, 0x00, 0x00, 0x48, 0x08, 0x01, 0x00, 0x81)) xknx = XKNX(loop=self.loop) knxipframe = KNXIPFrame(xknx) knxipframe.from_knx(raw) self.assertTrue(isinstance(knxipframe.body, TunnellingRequest)) self.assertEqual(knxipframe.body.communication_channel_id, 1) self.assertEqual(knxipframe.body.sequence_counter, 23) self.assertTrue(isinstance(knxipframe.body.cemi, CEMIFrame)) self.assertEqual(knxipframe.body.cemi.telegram, Telegram(GroupAddress('9/0/8'), payload=DPTBinary(1))) knxipframe2 = KNXIPFrame(xknx) knxipframe2.init(KNXIPServiceType.TUNNELLING_REQUEST) knxipframe2.body.cemi.telegram = Telegram(GroupAddress('9/0/8'), payload=DPTBinary(1)) knxipframe2.body.sequence_counter = 23 knxipframe2.normalize() self.assertEqual(knxipframe2.to_knx(), list(raw))
def test_set_operation_mode_with_separate_addresses(self): """Test set_operation_mode with combined and separated group adddresses defined.""" xknx = XKNX(loop=self.loop) climate = Climate(xknx, 'TestClimate', group_address_temperature='1/2/1', group_address_target_temperature='1/2/2', group_address_operation_mode='1/2/4', group_address_operation_mode_protection='1/2/5', group_address_operation_mode_night='1/2/6', group_address_operation_mode_comfort='1/2/7') self.loop.run_until_complete( asyncio.Task(climate.set_operation_mode( HVACOperationMode.COMFORT))) self.assertEqual(xknx.telegrams.qsize(), 4) telegram = xknx.telegrams.get_nowait() self.assertEqual(telegram, Telegram(GroupAddress('1/2/4'), payload=DPTArray(1))) telegram = xknx.telegrams.get_nowait() self.assertEqual(telegram, Telegram(GroupAddress('1/2/5'), payload=DPTBinary(0))) telegram = xknx.telegrams.get_nowait() self.assertEqual(telegram, Telegram(GroupAddress('1/2/6'), payload=DPTBinary(0))) telegram = xknx.telegrams.get_nowait() self.assertEqual(telegram, Telegram(GroupAddress('1/2/7'), payload=DPTBinary(1)))
def from_knx(self, payload): """Convert current payload to value.""" if payload == DPTBinary(0): return self.Direction.DECREASE if self.invert else self.Direction.INCREASE elif payload == DPTBinary(1): return self.Direction.INCREASE if self.invert else self.Direction.DECREASE raise ConversionError(payload)
def test_from_knx_invert(self): """Test from_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueStep(xknx, invert=True) self.assertEqual(remote_value.from_knx(DPTBinary(0)), RemoteValueStep.Direction.DECREASE) self.assertEqual(remote_value.from_knx(DPTBinary(1)), RemoteValueStep.Direction.INCREASE)
def test_to_knx_invert(self): """Test to_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueUpDown(xknx, invert=True) self.assertEqual(remote_value.to_knx(RemoteValueUpDown.Direction.UP), DPTBinary(1)) self.assertEqual(remote_value.to_knx(RemoteValueUpDown.Direction.DOWN), DPTBinary(0))
def test_from_knx_invert(self): """Test from_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueSwitch(xknx, invert=True) self.assertEqual(remote_value.from_knx(DPTBinary(1)), RemoteValueSwitch.Value.OFF) self.assertEqual(remote_value.from_knx(DPTBinary(0)), RemoteValueSwitch.Value.ON)
def test_from_knx_startstop(self): """Test from_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueStartStopDimming(xknx) self.assertEqual(remote_value.from_knx(DPTBinary(9)), RemoteValueStartStopDimming.Direction.INCREASE) self.assertEqual(remote_value.from_knx(DPTBinary(1)), RemoteValueStartStopDimming.Direction.DECREASE)
def test_to_knx(self): """Test to_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueSwitch(xknx) self.assertEqual(remote_value.to_knx(RemoteValueSwitch.Value.ON), DPTBinary(1)) self.assertEqual(remote_value.to_knx(RemoteValueSwitch.Value.OFF), DPTBinary(0))
def test_from_knx(self): """Test from_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueUpDown(xknx) self.assertEqual(remote_value.from_knx(DPTBinary(0)), RemoteValueUpDown.Direction.UP) self.assertEqual(remote_value.from_knx(DPTBinary(1)), RemoteValueUpDown.Direction.DOWN)
def test_from_knx_startstop_invert(self): """Test from_knx function with inverted operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueStartStopBlinds(xknx, invert=True) self.assertEqual(remote_value.from_knx(DPTBinary(9)), RemoteValueStartStopBlinds.Direction.UP) self.assertEqual(remote_value.from_knx(DPTBinary(1)), RemoteValueStartStopBlinds.Direction.DOWN)
def test_compare_none(self): self.assertEqual(DPTArray(()), None) self.assertEqual(None, DPTArray(())) self.assertEqual(DPTBinary(0), None) self.assertEqual(None, DPTBinary(0)) self.assertNotEqual(DPTArray((1, 2, 3)), None) self.assertNotEqual(None, DPTArray((1, 2, 3))) self.assertNotEqual(DPTBinary(1), None) self.assertNotEqual(None, DPTBinary(1))
def to_knx(self, value): """Convert value to payload.""" if value == self.Value.OFF: return DPTBinary(1) if self.invert else DPTBinary(0) if value == self.Value.ON: return DPTBinary(0) if self.invert else DPTBinary(1) raise ConversionError("value invalid", value=value, device_name=self.device_name)
def test_to_knx(self): """Test to_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueStep(xknx) self.assertEqual( remote_value.to_knx(RemoteValueStep.Direction.INCREASE), DPTBinary(0)) self.assertEqual( remote_value.to_knx(RemoteValueStep.Direction.DECREASE), DPTBinary(1))
def test_compare_none(self): """Test comparison of empty DPTArray objects with None.""" self.assertEqual(DPTArray(()), None) self.assertEqual(None, DPTArray(())) self.assertEqual(DPTBinary(0), None) self.assertEqual(None, DPTBinary(0)) self.assertNotEqual(DPTArray((1, 2, 3)), None) self.assertNotEqual(None, DPTArray((1, 2, 3))) self.assertNotEqual(DPTBinary(1), None) self.assertNotEqual(None, DPTBinary(1))
def test_to_knx_startstop_invert(self): """Test to_knx function with inverted operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueStartStopDimming(xknx, invert=True) self.assertEqual( remote_value.to_knx( RemoteValueStartStopDimming.Direction.INCREASE), DPTBinary(1)) self.assertEqual( remote_value.to_knx( RemoteValueStartStopDimming.Direction.DECREASE), DPTBinary(9))
def test_to_knx_startstop(self): """Test to_knx function with normal operation.""" xknx = XKNX(loop=self.loop) remote_value = RemoteValueStartStopBlinds(xknx) self.assertEqual( remote_value.to_knx(RemoteValueStartStopBlinds.Direction.DOWN), DPTBinary(9)) self.assertEqual( remote_value.to_knx(RemoteValueStartStopBlinds.Direction.UP), DPTBinary(1))