def test_xknx_start(self, start_mock): """Test xknx start.""" xknx = XKNX(state_updater=True) self.loop.run_until_complete(xknx.start()) start_mock.assert_called_once() self.loop.run_until_complete(xknx.stop())
def test_xknx_start_and_stop_with_dedicated_connection_config( self, start_mock): """Test xknx start and stop with connection config.""" xknx = XKNX() connection_config = ConnectionConfig( connection_type=ConnectionType.TUNNELING) xknx.connection_config = connection_config self.loop.run_until_complete(xknx.start()) start_mock.assert_called_once() self.assertEqual(xknx.knxip_interface.connection_config, connection_config) self.loop.run_until_complete(xknx.stop()) self.assertIsNone(xknx.knxip_interface) self.assertTrue(xknx.telegram_queue._consumer_task.done()) self.assertFalse(xknx.state_updater.started)
def send_to_ga(self, ga, dpt, value): """ Connect to the KNX bus and set a value. """ if not self.busaccess: logging.warning( "Busaccess disabled, not sending val(%s) to ga(%s)", value, ga ) return loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) xknx = XKNX() if "connection" in self.config: connection_types = { "tunneling": ConnectionType.TUNNELING, "routing": ConnectionType.ROUTING, "auto": ConnectionType.AUTOMATIC, } connection_config = ConnectionConfig( connection_type=connection_types[ self.config["connection"].get("type", "auto") ], gateway_ip=self.config["connection"].get("gateway_ip", None), gateway_port=self.config["connection"].get( "gateway_port", DEFAULT_MCAST_PORT ), local_ip=self.config["connection"].get("local_ip", None), auto_reconnect=self.config["connection"].get("autoReconnect", True), ) logging.debug("Applying custom connection config %s", connection_config) xknx.connection_config = connection_config loop.run_until_complete(xknx.start()) expose_sensor = ExposeSensor( xknx, "CalendarSensor", group_address=ga, value_type=dpt ) logging.info("Sending val(%s) to ga(%s)", value, ga) loop.run_until_complete(expose_sensor.set(value)) logging.debug(expose_sensor) loop.run_until_complete(xknx.stop())
#!/usr/bin/python3 from xknx import XKNX, Config import time def telegram_received_callback(xknx, device, telegram): print("Callback received from {0}".format(device.name)) if (device.name == "Livingroom.Switch_1"): if device.is_on(): xknx.devices["Livingroom.Outlet_1"].set_on() elif device.is_off(): xknx.devices["Livingroom.Outlet_1"].set_off() xknx = XKNX() Config(xknx).read() xknx.start(True, telegram_received_callback=telegram_received_callback)
class KNXModule(object): """Representation of KNX Object.""" def __init__(self, hass, config): """Initialize of KNX module.""" self.hass = hass self.config = config self.connected = False self.init_xknx() self.register_callbacks() def init_xknx(self): """Initialize of KNX object.""" from xknx import XKNX self.xknx = XKNX(config=self.config_file(), loop=self.hass.loop) @asyncio.coroutine def start(self): """Start KNX object. Connect to tunneling or Routing device.""" connection_config = self.connection_config() yield from self.xknx.start( state_updater=self.config[DOMAIN][CONF_KNX_STATE_UPDATER], connection_config=connection_config) self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.stop) self.connected = True @asyncio.coroutine def stop(self, event): """Stop KNX object. Disconnect from tunneling or Routing device.""" yield from self.xknx.stop() def config_file(self): """Resolve and return the full path of xknx.yaml if configured.""" config_file = self.config[DOMAIN].get(CONF_KNX_CONFIG) if not config_file: return None if not config_file.startswith("/"): return self.hass.config.path(config_file) return config_file def connection_config(self): """Return the connection_config.""" if CONF_KNX_TUNNELING in self.config[DOMAIN]: return self.connection_config_tunneling() elif CONF_KNX_ROUTING in self.config[DOMAIN]: return self.connection_config_routing() return self.connection_config_auto() def connection_config_routing(self): """Return the connection_config if routing is configured.""" from xknx.io import ConnectionConfig, ConnectionType local_ip = \ self.config[DOMAIN][CONF_KNX_ROUTING].get(CONF_KNX_LOCAL_IP) return ConnectionConfig(connection_type=ConnectionType.ROUTING, local_ip=local_ip) def connection_config_tunneling(self): """Return the connection_config if tunneling is configured.""" from xknx.io import ConnectionConfig, ConnectionType, \ DEFAULT_MCAST_PORT gateway_ip = \ self.config[DOMAIN][CONF_KNX_TUNNELING].get(CONF_HOST) gateway_port = \ self.config[DOMAIN][CONF_KNX_TUNNELING].get(CONF_PORT) local_ip = \ self.config[DOMAIN][CONF_KNX_TUNNELING].get(CONF_KNX_LOCAL_IP) if gateway_port is None: gateway_port = DEFAULT_MCAST_PORT return ConnectionConfig(connection_type=ConnectionType.TUNNELING, gateway_ip=gateway_ip, gateway_port=gateway_port, local_ip=local_ip) def connection_config_auto(self): """Return the connection_config if auto is configured.""" # pylint: disable=no-self-use from xknx.io import ConnectionConfig return ConnectionConfig() def register_callbacks(self): """Register callbacks within XKNX object.""" if CONF_KNX_FIRE_EVENT in self.config[DOMAIN] and \ self.config[DOMAIN][CONF_KNX_FIRE_EVENT]: from xknx.knx import AddressFilter address_filters = list( map(AddressFilter, self.config[DOMAIN][CONF_KNX_FIRE_EVENT_FILTER])) self.xknx.telegram_queue.register_telegram_received_cb( self.telegram_received_cb, address_filters) @asyncio.coroutine def telegram_received_cb(self, telegram): """Call invoked after a KNX telegram was received.""" self.hass.bus.fire( 'knx_event', { 'address': telegram.group_address.str(), 'data': telegram.payload.value }) # False signals XKNX to proceed with processing telegrams. return False @asyncio.coroutine def service_send_to_knx_bus(self, call): """Service for sending an arbitrary KNX message to the KNX bus.""" from xknx.knx import Telegram, GroupAddress, DPTBinary, DPTArray attr_payload = call.data.get(SERVICE_KNX_ATTR_PAYLOAD) attr_address = call.data.get(SERVICE_KNX_ATTR_ADDRESS) def calculate_payload(attr_payload): """Calculate payload depending on type of attribute.""" if isinstance(attr_payload, int): return DPTBinary(attr_payload) return DPTArray(attr_payload) payload = calculate_payload(attr_payload) address = GroupAddress(attr_address) telegram = Telegram() telegram.payload = payload telegram.group_address = address yield from self.xknx.telegrams.put(telegram)
class KNXModule(object): """Representation of KNX Object.""" def __init__(self, hass, config): """Initialize of KNX module.""" self.hass = hass self.config = config self.connected = False self.initialized = True self.init_xknx() self.register_callbacks() def init_xknx(self): """Initialize of KNX object.""" from xknx import XKNX self.xknx = XKNX(config=self.config_file(), loop=self.hass.loop) @asyncio.coroutine def start(self): """Start KNX object. Connect to tunneling or Routing device.""" connection_config = self.connection_config() yield from self.xknx.start( state_updater=self.config[DOMAIN][CONF_KNX_STATE_UPDATER], connection_config=connection_config) self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.stop) self.connected = True @asyncio.coroutine def stop(self, event): """Stop KNX object. Disconnect from tunneling or Routing device.""" yield from self.xknx.stop() def config_file(self): """Resolve and return the full path of xknx.yaml if configured.""" config_file = self.config[DOMAIN].get(CONF_KNX_CONFIG) if not config_file: return None if not config_file.startswith("/"): return self.hass.config.path(config_file) return config_file def connection_config(self): """Return the connection_config.""" if CONF_KNX_TUNNELING in self.config[DOMAIN]: return self.connection_config_tunneling() elif CONF_KNX_ROUTING in self.config[DOMAIN]: return self.connection_config_routing() return self.connection_config_auto() def connection_config_routing(self): """Return the connection_config if routing is configured.""" from xknx.io import ConnectionConfig, ConnectionType local_ip = \ self.config[DOMAIN][CONF_KNX_ROUTING].get(CONF_KNX_LOCAL_IP) return ConnectionConfig( connection_type=ConnectionType.ROUTING, local_ip=local_ip) def connection_config_tunneling(self): """Return the connection_config if tunneling is configured.""" from xknx.io import ConnectionConfig, ConnectionType, \ DEFAULT_MCAST_PORT gateway_ip = \ self.config[DOMAIN][CONF_KNX_TUNNELING].get(CONF_HOST) gateway_port = \ self.config[DOMAIN][CONF_KNX_TUNNELING].get(CONF_PORT) local_ip = \ self.config[DOMAIN][CONF_KNX_TUNNELING].get(CONF_KNX_LOCAL_IP) if gateway_port is None: gateway_port = DEFAULT_MCAST_PORT return ConnectionConfig( connection_type=ConnectionType.TUNNELING, gateway_ip=gateway_ip, gateway_port=gateway_port, local_ip=local_ip) def connection_config_auto(self): """Return the connection_config if auto is configured.""" # pylint: disable=no-self-use from xknx.io import ConnectionConfig return ConnectionConfig() def register_callbacks(self): """Register callbacks within XKNX object.""" if CONF_KNX_FIRE_EVENT in self.config[DOMAIN] and \ self.config[DOMAIN][CONF_KNX_FIRE_EVENT]: from xknx.knx import AddressFilter address_filters = list(map( AddressFilter, self.config[DOMAIN][CONF_KNX_FIRE_EVENT_FILTER])) self.xknx.telegram_queue.register_telegram_received_cb( self.telegram_received_cb, address_filters) @asyncio.coroutine def telegram_received_cb(self, telegram): """Call invoked after a KNX telegram was received.""" self.hass.bus.fire('knx_event', { 'address': telegram.group_address.str(), 'data': telegram.payload.value }) # False signals XKNX to proceed with processing telegrams. return False @asyncio.coroutine def service_send_to_knx_bus(self, call): """Service for sending an arbitrary KNX message to the KNX bus.""" from xknx.knx import Telegram, Address, DPTBinary, DPTArray attr_payload = call.data.get(SERVICE_KNX_ATTR_PAYLOAD) attr_address = call.data.get(SERVICE_KNX_ATTR_ADDRESS) def calculate_payload(attr_payload): """Calculate payload depending on type of attribute.""" if isinstance(attr_payload, int): return DPTBinary(attr_payload) return DPTArray(attr_payload) payload = calculate_payload(attr_payload) address = Address(attr_address) telegram = Telegram() telegram.payload = payload telegram.group_address = address yield from self.xknx.telegrams.put(telegram)