def main(): """ Example application that opens a device that has been exposed to the network with ser2sock and SSL encryption and authentication. """ try: # Retrieve an AD2 device that has been exposed with ser2sock on localhost:10000. ssl_device = SocketDevice(interface=('localhost', 10000)) # Enable SSL and set the certificates to be used. # # The key/cert attributes can either be a filesystem path or an X509/PKey # object from pyopenssl. ssl_device.ssl = True ssl_device.ssl_ca = SSL_CA # CA certificate ssl_device.ssl_key = SSL_KEY # Client private key ssl_device.ssl_certificate = SSL_CERT # Client certificate device = AlarmDecoder(ssl_device) # Set up an event handler and open the device device.on_message += handle_message with device.open(): while True: time.sleep(1) except Exception, ex: print 'Exception:', ex
async def async_step_protocol(self, user_input=None): """Handle AlarmDecoder protocol setup.""" errors = {} if user_input is not None: if _device_already_added( self._async_current_entries(), user_input, self.protocol ): return self.async_abort(reason="already_configured") connection = {} baud = None if self.protocol == PROTOCOL_SOCKET: host = connection[CONF_HOST] = user_input[CONF_HOST] port = connection[CONF_PORT] = user_input[CONF_PORT] title = f"{host}:{port}" device = SocketDevice(interface=(host, port)) if self.protocol == PROTOCOL_SERIAL: path = connection[CONF_DEVICE_PATH] = user_input[CONF_DEVICE_PATH] baud = connection[CONF_DEVICE_BAUD] = user_input[CONF_DEVICE_BAUD] title = path device = SerialDevice(interface=path) controller = AdExt(device) def test_connection(): controller.open(baud) controller.close() try: await self.hass.async_add_executor_job(test_connection) return self.async_create_entry( title=title, data={CONF_PROTOCOL: self.protocol, **connection} ) except NoDeviceError: errors["base"] = "cannot_connect" except Exception: # pylint: disable=broad-except _LOGGER.exception("Unexpected exception during AlarmDecoder setup") errors["base"] = "unknown" if self.protocol == PROTOCOL_SOCKET: schema = vol.Schema( { vol.Required(CONF_HOST, default=DEFAULT_DEVICE_HOST): str, vol.Required(CONF_PORT, default=DEFAULT_DEVICE_PORT): int, } ) if self.protocol == PROTOCOL_SERIAL: schema = vol.Schema( { vol.Required(CONF_DEVICE_PATH, default=DEFAULT_DEVICE_PATH): str, vol.Required(CONF_DEVICE_BAUD, default=DEFAULT_DEVICE_BAUD): int, } ) return self.async_show_form( step_id="protocol", data_schema=schema, errors=errors, )
def main(): """ Example application that opens a device that has been exposed to the network with ser2sock or similar serial-to-IP software. """ try: # Retrieve an AD2 device that has been exposed with ser2sock on localhost:10000. device = AlarmDecoder(SocketDevice(interface=(HOSTNAME, PORT))) # Set up an event handler and open the device device.on_message += handle_message with device.open(): while True: time.sleep(1) except Exception as ex: print('Exception:', ex)
def async_setup(hass, config): """Set up for the AlarmDecoder devices.""" from alarmdecoder import AlarmDecoder from alarmdecoder.devices import (SocketDevice, SerialDevice, USBDevice) conf = config.get(DOMAIN) device = conf.get(CONF_DEVICE) display = conf.get(CONF_PANEL_DISPLAY) zones = conf.get(CONF_ZONES) device_type = device.get(CONF_DEVICE_TYPE) host = DEFAULT_DEVICE_HOST port = DEFAULT_DEVICE_PORT path = DEFAULT_DEVICE_PATH baud = DEFAULT_DEVICE_BAUD sync_connect = asyncio.Future(loop=hass.loop) def handle_open(device): """Handle the successful connection.""" _LOGGER.info("Established a connection with the alarmdecoder") hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder) sync_connect.set_result(True) @callback def stop_alarmdecoder(event): """Handle the shutdown of AlarmDecoder.""" _LOGGER.debug("Shutting down alarmdecoder") controller.close() @callback def handle_message(sender, message): """Handle message from AlarmDecoder.""" async_dispatcher_send(hass, SIGNAL_PANEL_MESSAGE, message) def zone_fault_callback(sender, zone): """Handle zone fault from AlarmDecoder.""" async_dispatcher_send(hass, SIGNAL_ZONE_FAULT, zone) def zone_restore_callback(sender, zone): """Handle zone restore from AlarmDecoder.""" async_dispatcher_send(hass, SIGNAL_ZONE_RESTORE, zone) controller = False if device_type == 'socket': host = device.get(CONF_DEVICE_HOST) port = device.get(CONF_DEVICE_PORT) controller = AlarmDecoder(SocketDevice(interface=(host, port))) elif device_type == 'serial': path = device.get(CONF_DEVICE_PATH) baud = device.get(CONF_DEVICE_BAUD) controller = AlarmDecoder(SerialDevice(interface=path)) elif device_type == 'usb': AlarmDecoder(USBDevice.find()) return False controller.on_open += handle_open controller.on_message += handle_message controller.on_zone_fault += zone_fault_callback controller.on_zone_restore += zone_restore_callback hass.data[DATA_AD] = controller controller.open(baud) result = yield from sync_connect if not result: return False hass.async_add_job( async_load_platform(hass, 'alarm_control_panel', DOMAIN, conf, config)) if zones: hass.async_add_job( async_load_platform(hass, 'binary_sensor', DOMAIN, {CONF_ZONES: zones}, config)) if display: hass.async_add_job( async_load_platform(hass, 'sensor', DOMAIN, conf, config)) return True
def setup(hass, config): """Set up for the AlarmDecoder devices.""" from alarmdecoder import AlarmDecoder from alarmdecoder.devices import (SocketDevice, SerialDevice, USBDevice) conf = config.get(DOMAIN) restart = False device = conf.get(CONF_DEVICE) display = conf.get(CONF_PANEL_DISPLAY) zones = conf.get(CONF_ZONES) device_type = device.get(CONF_DEVICE_TYPE) host = DEFAULT_DEVICE_HOST port = DEFAULT_DEVICE_PORT path = DEFAULT_DEVICE_PATH baud = DEFAULT_DEVICE_BAUD def stop_alarmdecoder(event): """Handle the shutdown of AlarmDecoder.""" _LOGGER.debug("Shutting down alarmdecoder") nonlocal restart restart = False controller.close() def open_connection(now=None): """Open a connection to AlarmDecoder.""" from alarmdecoder.util import NoDeviceError nonlocal restart try: controller.open(baud) except NoDeviceError: _LOGGER.debug("Failed to connect. Retrying in 5 seconds") hass.helpers.event.track_point_in_time( open_connection, dt_util.utcnow() + timedelta(seconds=5)) return _LOGGER.debug("Established a connection with the alarmdecoder") restart = True def handle_closed_connection(event): """Restart after unexpected loss of connection.""" nonlocal restart if not restart: return restart = False _LOGGER.warning("AlarmDecoder unexpectedly lost connection.") hass.add_job(open_connection) def handle_message(sender, message): """Handle message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_PANEL_MESSAGE, message) def handle_rfx_message(sender, message): """Handle RFX message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_RFX_MESSAGE, message) def zone_fault_callback(sender, zone): """Handle zone fault from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_FAULT, zone) def zone_restore_callback(sender, zone): """Handle zone restore from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_RESTORE, zone) def handle_rel_message(sender, message): """Handle relay message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_REL_MESSAGE, message) controller = False if device_type == 'socket': host = device.get(CONF_DEVICE_HOST) port = device.get(CONF_DEVICE_PORT) controller = AlarmDecoder(SocketDevice(interface=(host, port))) elif device_type == 'serial': path = device.get(CONF_DEVICE_PATH) baud = device.get(CONF_DEVICE_BAUD) controller = AlarmDecoder(SerialDevice(interface=path)) elif device_type == 'usb': AlarmDecoder(USBDevice.find()) return False controller.on_message += handle_message controller.on_rfx_message += handle_rfx_message controller.on_zone_fault += zone_fault_callback controller.on_zone_restore += zone_restore_callback controller.on_close += handle_closed_connection controller.on_relay_changed += handle_rel_message hass.data[DATA_AD] = controller open_connection() hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder) load_platform(hass, 'alarm_control_panel', DOMAIN, conf, config) if zones: load_platform(hass, 'binary_sensor', DOMAIN, {CONF_ZONES: zones}, config) if display: load_platform(hass, 'sensor', DOMAIN, conf, config) return True
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: """Set up AlarmDecoder config flow.""" undo_listener = entry.add_update_listener(_update_listener) ad_connection = entry.data protocol = ad_connection[CONF_PROTOCOL] def stop_alarmdecoder(event): """Handle the shutdown of AlarmDecoder.""" if not hass.data.get(DOMAIN): return _LOGGER.debug("Shutting down alarmdecoder") hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = False controller.close() async def open_connection(now=None): """Open a connection to AlarmDecoder.""" try: await hass.async_add_executor_job(controller.open, baud) except NoDeviceError: _LOGGER.debug("Failed to connect. Retrying in 5 seconds") hass.helpers.event.async_track_point_in_time( open_connection, dt_util.utcnow() + timedelta(seconds=5)) return _LOGGER.debug("Established a connection with the alarmdecoder") hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = True def handle_closed_connection(event): """Restart after unexpected loss of connection.""" if not hass.data[DOMAIN][entry.entry_id][DATA_RESTART]: return hass.data[DOMAIN][entry.entry_id][DATA_RESTART] = False _LOGGER.warning("AlarmDecoder unexpectedly lost connection") hass.add_job(open_connection) def handle_message(sender, message): """Handle message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_PANEL_MESSAGE, message) def handle_rfx_message(sender, message): """Handle RFX message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_RFX_MESSAGE, message) def zone_fault_callback(sender, zone): """Handle zone fault from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_FAULT, zone) def zone_restore_callback(sender, zone): """Handle zone restore from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_RESTORE, zone) def handle_rel_message(sender, message): """Handle relay or zone expander message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_REL_MESSAGE, message) baud = ad_connection.get(CONF_DEVICE_BAUD) if protocol == PROTOCOL_SOCKET: host = ad_connection[CONF_HOST] port = ad_connection[CONF_PORT] controller = AdExt(SocketDevice(interface=(host, port))) if protocol == PROTOCOL_SERIAL: path = ad_connection[CONF_DEVICE_PATH] controller = AdExt(SerialDevice(interface=path)) controller.on_message += handle_message controller.on_rfx_message += handle_rfx_message controller.on_zone_fault += zone_fault_callback controller.on_zone_restore += zone_restore_callback controller.on_close += handle_closed_connection controller.on_expander_message += handle_rel_message remove_stop_listener = hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder) hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][entry.entry_id] = { DATA_AD: controller, DATA_REMOVE_UPDATE_LISTENER: undo_listener, DATA_REMOVE_STOP_LISTENER: remove_stop_listener, DATA_RESTART: False, } await open_connection() for platform in PLATFORMS: hass.async_create_task( hass.config_entries.async_forward_entry_setup(entry, platform)) return True
def setUp(self): self._device = SocketDevice() self._device._device = Mock(spec=socket.socket)
class TestSocketDevice(TestCase): def setUp(self): self._device = SocketDevice() self._device._device = Mock(spec=socket.socket) def tearDown(self): self._device.close() def test_open(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: self._device.open(no_reader_thread=True) mock.assert_called_with(self._device.interface) def test_open_failed(self): with patch.object(socket.socket, 'connect', side_effect=socket.error): with self.assertRaises(NoDeviceError): self._device.open(no_reader_thread=True) def test_write(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None): self._device.open(no_reader_thread=True) with patch.object(socket.socket, 'send') as mock: self._device.write(b'test') mock.assert_called_with(b'test') def test_write_exception(self): side_effects = [socket.error] if (have_openssl): side_effects.append(SSL.Error) with patch.object(self._device._device, 'send', side_effect=side_effects): with self.assertRaises(CommError): self._device.write(b'test') def test_read(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None): self._device.open(no_reader_thread=True) with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(socket.socket, 'recv') as mock: self._device.read() mock.assert_called_with(1) def test_read_exception(self): with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', side_effect=socket.error): with self.assertRaises(CommError): self._device.read() def test_read_line(self): side_effect = list("testing\r\n") if sys.version_info > (3, ): side_effect = [chr(x).encode('utf-8') for x in b"testing\r\n"] with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', side_effect=side_effect): ret = None try: ret = self._device.read_line() except StopIteration: pass self.assertEquals(ret, "testing") def test_read_line_timeout(self): with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', return_value=b'a') as mock: with self.assertRaises(TimeoutError): self._device.read_line(timeout=0.1) self.assertIn('a', self._device._buffer.decode('utf-8')) def test_read_line_exception(self): with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', side_effect=socket.error): with self.assertRaises(CommError): self._device.read_line() with self.assertRaises(CommError): self._device.read_line() def test_ssl(self): if not have_openssl: return ssl_key = crypto.PKey() ssl_key.generate_key(crypto.TYPE_RSA, 2048) ssl_cert = crypto.X509() ssl_cert.set_pubkey(ssl_key) ssl_ca_key = crypto.PKey() ssl_ca_key.generate_key(crypto.TYPE_RSA, 2048) ssl_ca_cert = crypto.X509() ssl_ca_cert.set_pubkey(ssl_ca_key) self._device.ssl = True self._device.ssl_key = ssl_key self._device.ssl_certificate = ssl_cert self._device.ssl_ca = ssl_ca_cert fileno, path = tempfile.mkstemp() # ..there has to be a better way.. with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: with patch.object(socket.socket, '_sock'): with patch.object(socket.socket, 'fileno', return_value=fileno): try: self._device.open(no_reader_thread=True) except SSL.SysCallError as ex: pass os.close(fileno) os.unlink(path) mock.assert_called_with(self._device.interface) self.assertIsInstance(self._device._device, SSL.Connection) def test_ssl_exception(self): if not have_openssl: return self._device.ssl = True self._device.ssl_key = 'None' self._device.ssl_certificate = 'None' self._device.ssl_ca = 'None' fileno, path = tempfile.mkstemp() # ..there has to be a better way.. with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: with patch.object(socket.socket, '_sock'): with patch.object(socket.socket, 'fileno', return_value=fileno): with self.assertRaises(CommError): try: self._device.open(no_reader_thread=True) except SSL.SysCallError as ex: pass os.close(fileno) os.unlink(path)
class TestSocketDevice(TestCase): def setUp(self): self._device = SocketDevice() self._device._device = Mock(spec=socket.socket) def tearDown(self): self._device.close() ### Tests def test_open(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: self._device.open(no_reader_thread=True) mock.assert_called_with(self._device.interface) def test_open_failed(self): with patch.object(socket.socket, 'connect', side_effect=socket.error): with self.assertRaises(NoDeviceError): self._device.open(no_reader_thread=True) def test_write(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None): self._device.open(no_reader_thread=True) with patch.object(socket.socket, 'send') as mock: self._device.write(b'test') mock.assert_called_with(b'test') def test_write_exception(self): side_effects = [socket.error] if (have_openssl): side_effects.append(SSL.Error) with patch.object(self._device._device, 'send', side_effect=side_effects): with self.assertRaises(CommError): self._device.write(b'test') def test_read(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None): self._device.open(no_reader_thread=True) with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(socket.socket, 'recv') as mock: self._device.read() mock.assert_called_with(1) def test_read_exception(self): with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', side_effect=socket.error): with self.assertRaises(CommError): self._device.read() def test_read_line(self): side_effect = list("testing\r\n") if sys.version_info > (3,): side_effect = [chr(x).encode('utf-8') for x in b"testing\r\n"] with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', side_effect=side_effect): ret = None try: ret = self._device.read_line() except StopIteration: pass self.assertEquals(ret, "testing") def test_read_line_timeout(self): with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', return_value=b'a') as mock: with self.assertRaises(TimeoutError): self._device.read_line(timeout=0.1) self.assertIn('a', self._device._buffer.decode('utf-8')) def test_read_line_exception(self): with patch('socket.socket.fileno', return_value=1): with patch.object(select, 'select', return_value=[[1], [], []]): with patch.object(self._device._device, 'recv', side_effect=socket.error): with self.assertRaises(CommError): self._device.read_line() with self.assertRaises(CommError): self._device.read_line() def test_ssl(self): if not have_openssl: return ssl_key = crypto.PKey() ssl_key.generate_key(crypto.TYPE_RSA, 2048) ssl_cert = crypto.X509() ssl_cert.set_pubkey(ssl_key) ssl_ca_key = crypto.PKey() ssl_ca_key.generate_key(crypto.TYPE_RSA, 2048) ssl_ca_cert = crypto.X509() ssl_ca_cert.set_pubkey(ssl_ca_key) self._device.ssl = True self._device.ssl_key = ssl_key self._device.ssl_certificate = ssl_cert self._device.ssl_ca = ssl_ca_cert fileno, path = tempfile.mkstemp() # ..there has to be a better way.. with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: with patch.object(socket.socket, '_sock'): with patch.object(socket.socket, 'fileno', return_value=fileno): try: self._device.open(no_reader_thread=True) except SSL.SysCallError as ex: pass os.close(fileno) os.unlink(path) mock.assert_called_with(self._device.interface) self.assertIsInstance(self._device._device, SSL.Connection) def test_ssl_exception(self): if not have_openssl: return self._device.ssl = True self._device.ssl_key = 'None' self._device.ssl_certificate = 'None' self._device.ssl_ca = 'None' fileno, path = tempfile.mkstemp() # ..there has to be a better way.. with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: with patch.object(socket.socket, '_sock'): with patch.object(socket.socket, 'fileno', return_value=fileno): with self.assertRaises(CommError): try: self._device.open(no_reader_thread=True) except SSL.SysCallError as ex: pass os.close(fileno) os.unlink(path)
def setup(hass, config): """Set up for the AlarmDecoder devices.""" conf = config.get(DOMAIN) restart = False device = conf[CONF_DEVICE] display = conf[CONF_PANEL_DISPLAY] auto_bypass = conf[CONF_AUTO_BYPASS] code_arm_required = conf[CONF_CODE_ARM_REQUIRED] zones = conf.get(CONF_ZONES) device_type = device[CONF_DEVICE_TYPE] host = DEFAULT_DEVICE_HOST port = DEFAULT_DEVICE_PORT path = DEFAULT_DEVICE_PATH baud = DEFAULT_DEVICE_BAUD def stop_alarmdecoder(event): """Handle the shutdown of AlarmDecoder.""" _LOGGER.debug("Shutting down alarmdecoder") nonlocal restart restart = False controller.close() def open_connection(now=None): """Open a connection to AlarmDecoder.""" nonlocal restart try: controller.open(baud) except NoDeviceError: _LOGGER.debug("Failed to connect. Retrying in 5 seconds") hass.helpers.event.track_point_in_time( open_connection, dt_util.utcnow() + timedelta(seconds=5)) return _LOGGER.debug("Established a connection with the alarmdecoder") restart = True def handle_closed_connection(event): """Restart after unexpected loss of connection.""" nonlocal restart if not restart: return restart = False _LOGGER.warning("AlarmDecoder unexpectedly lost connection") hass.add_job(open_connection) def handle_message(sender, message): """Handle message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_PANEL_MESSAGE, message) def handle_rfx_message(sender, message): """Handle RFX message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_RFX_MESSAGE, message) def zone_fault_callback(sender, zone): """Handle zone fault from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_FAULT, zone) def zone_restore_callback(sender, zone): """Handle zone restore from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_RESTORE, zone) def handle_rel_message(sender, message): """Handle relay or zone expander message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_REL_MESSAGE, message) controller = False if device_type == "socket": host = device[CONF_HOST] port = device[CONF_DEVICE_PORT] controller = AdExt(SocketDevice(interface=(host, port))) elif device_type == "serial": path = device[CONF_DEVICE_PATH] baud = device[CONF_DEVICE_BAUD] controller = AdExt(SerialDevice(interface=path)) elif device_type == "usb": AdExt(USBDevice.find()) return False controller.on_message += handle_message controller.on_rfx_message += handle_rfx_message controller.on_zone_fault += zone_fault_callback controller.on_zone_restore += zone_restore_callback controller.on_close += handle_closed_connection controller.on_expander_message += handle_rel_message hass.data[DATA_AD] = controller open_connection() hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder) load_platform( hass, "alarm_control_panel", DOMAIN, { CONF_AUTO_BYPASS: auto_bypass, CONF_CODE_ARM_REQUIRED: code_arm_required }, config, ) if zones: load_platform(hass, "binary_sensor", DOMAIN, {CONF_ZONES: zones}, config) if display: load_platform(hass, "sensor", DOMAIN, conf, config) return True
class TestSocketDevice(TestCase): def setUp(self): self._device = SocketDevice() self._device._device = Mock(spec=socket.socket) def tearDown(self): self._device.close() def test_open(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: self._device.open(no_reader_thread=True) mock.assert_called_with(self._device.interface) def test_open_failed(self): with patch.object(socket.socket, 'connect', side_effect=socket.error): with self.assertRaises(NoDeviceError): self._device.open(no_reader_thread=True) def test_write(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None): self._device.open(no_reader_thread=True) with patch.object(socket.socket, 'send') as mock: self._device.write('test') mock.assert_called_with('test') def test_write_exception(self): with patch.object(self._device._device, 'send', side_effect=[SSL.Error, socket.error]): with self.assertRaises(CommError): self._device.write('test') def test_read(self): with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None): self._device.open(no_reader_thread=True) with patch.object(socket.socket, 'recv') as mock: self._device.read() mock.assert_called_with(1) def test_read_exception(self): with patch.object(self._device._device, 'recv', side_effect=socket.error): with self.assertRaises(CommError): self._device.read() def test_read_line(self): with patch.object(self._device._device, 'recv', side_effect=list("testing\r\n")): ret = None try: ret = self._device.read_line() except StopIteration: pass self.assertEquals(ret, "testing") def test_read_line_timeout(self): with patch.object(self._device._device, 'recv', return_value='a') as mock: with self.assertRaises(TimeoutError): self._device.read_line(timeout=0.1) self.assertIn('a', self._device._buffer) def test_read_line_exception(self): with patch.object(self._device._device, 'recv', side_effect=socket.error): with self.assertRaises(CommError): self._device.read_line() with self.assertRaises(CommError): self._device.read_line() def test_ssl(self): ssl_key = crypto.PKey() ssl_key.generate_key(crypto.TYPE_RSA, 2048) ssl_cert = crypto.X509() ssl_cert.set_pubkey(ssl_key) ssl_ca_key = crypto.PKey() ssl_ca_key.generate_key(crypto.TYPE_RSA, 2048) ssl_ca_cert = crypto.X509() ssl_ca_cert.set_pubkey(ssl_ca_key) self._device.ssl = True self._device.ssl_key = ssl_key self._device.ssl_certificate = ssl_cert self._device.ssl_ca = ssl_ca_cert fileno, path = tempfile.mkstemp() # ..there has to be a better way.. with patch.object(socket.socket, '__init__', return_value=None): with patch.object(socket.socket, 'connect', return_value=None) as mock: with patch.object(socket.socket, '_sock'): with patch.object(socket.socket, 'fileno', return_value=fileno): try: self._device.open(no_reader_thread=True) except SSL.SysCallError, ex: pass os.close(fileno) os.unlink(path) mock.assert_called_with(self._device.interface) self.assertIsInstance(self._device._device, SSL.Connection)