-
-
Notifications
You must be signed in to change notification settings - Fork 37.8k
Add All-Linking capabilities #14065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add All-Linking capabilities #14065
Changes from 30 commits
be3064a
55798c6
4d9d25d
eda460c
e81872c
145e849
5fe240a
ce35e07
2378f3a
e805acd
603fcdb
adc1073
db22601
52c870c
a51cef8
d527435
decc72f
69f93ae
a0b5082
5a9f041
1c93eac
8d3332e
3f9804e
875dc50
1c30d74
ea3cb13
fe3f2da
a45ef02
11c7eaf
218a8be
cd959f9
9699000
52665f6
fa63eee
e4c1ff7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,12 +11,13 @@ | |
|
|
||
| from homeassistant.core import callback | ||
| from homeassistant.const import (CONF_PORT, EVENT_HOMEASSISTANT_STOP, | ||
| CONF_PLATFORM) | ||
| CONF_PLATFORM, | ||
| CONF_ENTITY_ID) | ||
| import homeassistant.helpers.config_validation as cv | ||
| from homeassistant.helpers import discovery | ||
| from homeassistant.helpers.entity import Entity | ||
|
|
||
| REQUIREMENTS = ['insteonplm==0.8.6'] | ||
| REQUIREMENTS = ['insteonplm==0.9.1'] | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
|
|
@@ -29,6 +30,17 @@ | |
| CONF_FIRMWARE = 'firmware' | ||
| CONF_PRODUCT_KEY = 'product_key' | ||
|
|
||
| SRV_ADD_ALL_LINK = 'add_all_link' | ||
| SRV_DEL_ALL_LINK = 'delete_all_link' | ||
| SRV_LOAD_ALDB = 'load_all_link_database' | ||
| SRV_PRINT_ALDB = 'print_all_link_database' | ||
| SRV_PRINT_IM_ALDB = 'print_im_all_link_database' | ||
| SRV_ALL_LINK_GROUP = 'group' | ||
| SRV_ALL_LINK_MODE = 'mode' | ||
| SRV_LOAD_DB_RELOAD = 'reload' | ||
| SRV_CONTROLLER = 'controller' | ||
| SRV_RESPONDER = 'responder' | ||
|
|
||
| CONF_DEVICE_OVERRIDE_SCHEMA = vol.All( | ||
| cv.deprecated(CONF_PLATFORM), vol.Schema({ | ||
| vol.Required(CONF_ADDRESS): cv.string, | ||
|
|
@@ -47,13 +59,32 @@ | |
| }) | ||
| }, extra=vol.ALLOW_EXTRA) | ||
|
|
||
| ADD_ALL_LINK_SCHEMA = vol.Schema({ | ||
| vol.Required(SRV_ALL_LINK_GROUP): vol.Range(min=0, max=255), | ||
| vol.Required(SRV_ALL_LINK_MODE): vol.In([SRV_CONTROLLER, SRV_RESPONDER]), | ||
| }) | ||
|
|
||
| DEL_ALL_LINK_SCHEMA = vol.Schema({ | ||
| vol.Required(SRV_ALL_LINK_GROUP): vol.Range(min=0, max=255), | ||
| }) | ||
|
|
||
| LOAD_ALDB_SCHEMA = vol.Schema({ | ||
| vol.Required(CONF_ENTITY_ID): cv.entity_id, | ||
| vol.Optional(SRV_LOAD_DB_RELOAD, default='false'): vol.boolean, | ||
| }) | ||
|
|
||
| PRINT_ALDB_SCHEMA = vol.Schema({ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. continuation line missing indentation or outdented |
||
| vol.Required(CONF_ENTITY_ID): cv.entity_id, | ||
| }) | ||
|
|
||
|
|
||
| @asyncio.coroutine | ||
| def async_setup(hass, config): | ||
| """Set up the connection to the PLM.""" | ||
| import insteonplm | ||
|
|
||
| ipdb = IPDB() | ||
| plm = None | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unexpected spaces around keyword / parameter equals There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unexpected spaces around keyword / parameter equals |
||
|
|
||
| conf = config[DOMAIN] | ||
| port = conf.get(CONF_PORT) | ||
|
|
@@ -79,6 +110,63 @@ def async_plm_new_device(device): | |
| 'state_key': state_key}, | ||
| hass_config=config)) | ||
|
|
||
| def add_all_link(service): | ||
| """Add an INSTEON All-Link between two devices.""" | ||
| group = service.data.get(SRV_ALL_LINK_GROUP) | ||
| mode = service.data.get(SRV_ALL_LINK_MODE) | ||
| link_mode = 1 if mode.lower() == SRV_CONTROLLER else 0 | ||
| plm.start_all_linking(link_mode, group) | ||
|
|
||
| def del_all_link(service): | ||
| """Delete an INSTEON All-Link between two devices.""" | ||
| group = service.data.get(SRV_ALL_LINK_GROUP) | ||
| plm.start_all_linking(255, group) | ||
|
|
||
| def load_aldb(service): | ||
| """Load the device All-Link database.""" | ||
| entity_id = service.data.get(CONF_ENTITY_ID) | ||
| reload = service.data.get(SRV_LOAD_DB_RELOAD) | ||
| db_reload = False | ||
| if reload: | ||
| db_reload = True if reload.lower() == 'y' else False | ||
| entities = hass.data[DOMAIN].get('entities') | ||
| entity = entities.get(entity_id) | ||
| if entity: | ||
| entity.load_aldb(db_reload) | ||
| else: | ||
| _LOGGER.error('Entity %s is not an INSTEON device', entity_id) | ||
|
|
||
| def print_aldb(service): | ||
| """Print the All-Link Database for a device.""" | ||
| # For now this sends logs to the log file. | ||
| # Furture direction is to create an INSTEON control panel. | ||
| entity_id = service.data.get(CONF_ENTITY_ID) | ||
| entities = hass.data[DOMAIN].get('entities') | ||
| entity = entities.get(entity_id) | ||
| if entity: | ||
| entity.print_aldb() | ||
| else: | ||
| _LOGGER.error('Entity %s is not an INSTEON device', entity_id) | ||
|
|
||
| def print_im_aldb(service): | ||
| """Print the All-Link Database for a device.""" | ||
| # For now this sends logs to the log file. | ||
| # Furture direction is to create an INSTEON control panel. | ||
| print_aldb_to_log(plm.aldb) | ||
|
|
||
| def _register_services(): | ||
| hass.services.register(DOMAIN, SRV_ADD_ALL_LINK, add_all_link, | ||
| schema=ADD_ALL_LINK_SCHEMA) | ||
| hass.services.register(DOMAIN, SRV_DEL_ALL_LINK, del_all_link, | ||
| schema=DEL_ALL_LINK_SCHEMA) | ||
| hass.services.register(DOMAIN, SRV_LOAD_ALDB, load_aldb, | ||
| schema=LOAD_ALDB_SCHEMA) | ||
| hass.services.register(DOMAIN, SRV_PRINT_ALDB, print_aldb, | ||
| schema=PRINT_ALDB_SCHEMA) | ||
| hass.services.register(DOMAIN, SRV_PRINT_IM_ALDB, print_im_aldb, | ||
| schema=None) | ||
| _LOGGER.debug("Insteon_plm Services registered") | ||
|
|
||
| _LOGGER.info("Looking for PLM on %s", port) | ||
| conn = yield from insteonplm.Connection.create( | ||
| device=port, | ||
|
|
@@ -100,11 +188,14 @@ def async_plm_new_device(device): | |
| plm.devices.add_override(address, CONF_PRODUCT_KEY, | ||
| device_override[prop]) | ||
|
|
||
| hass.data['insteon_plm'] = plm | ||
| hass.data[DOMAIN] = {} | ||
| hass.data[DOMAIN]['plm'] = plm | ||
| hass.data[DOMAIN]['entities'] = {} | ||
|
|
||
| hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, conn.close) | ||
|
|
||
| plm.devices.add_device_callback(async_plm_new_device) | ||
| hass.async_add_job(_register_services) | ||
|
|
||
| return True | ||
|
|
||
|
|
@@ -169,6 +260,7 @@ def __init__(self, device, state_key): | |
| """Initialize the INSTEON PLM binary sensor.""" | ||
| self._insteon_device_state = device.states[state_key] | ||
| self._insteon_device = device | ||
| self._insteon_device.aldb.add_loaded_callback(self._aldb_loaded) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should not print anything during startup. Print when requested via a service is ok.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is not printing here. It is registering a callback.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my bad. Was confused because the callback will print, but I guess it only prints when asked to load. |
||
|
|
||
| @property | ||
| def should_poll(self): | ||
|
|
@@ -215,3 +307,46 @@ def async_added_to_hass(self): | |
| """Register INSTEON update events.""" | ||
| self._insteon_device_state.register_updates( | ||
| self.async_entity_update) | ||
| self.hass.data[DOMAIN]['entities'][self.entity_id] = self | ||
|
|
||
| def load_aldb(self, reload=False): | ||
| """Load the device All-Link Database.""" | ||
| if reload: | ||
| self._insteon_device.aldb.clear() | ||
| self._insteon_device.read_aldb() | ||
|
|
||
| def print_aldb(self): | ||
| """Print the device ALDB to the log file.""" | ||
| print_aldb_to_log(self._insteon_device.aldb) | ||
|
|
||
| @callback | ||
| def _aldb_loaded(self): | ||
| """All-Link Database loaded for the device.""" | ||
| self.print_aldb() | ||
|
|
||
|
|
||
| def print_aldb_to_log(aldb): | ||
| """Print the All-Link Database to the log file.""" | ||
| from insteonplm.devices import ALDBStatus | ||
| _LOGGER.info('ALDB load status is %s', aldb.status.name) | ||
| if aldb.status not in [ALDBStatus.LOADED, ALDBStatus.PARTIAL]: | ||
| _LOGGER.warning('Device All-Link database not loaded') | ||
| _LOGGER.warning('Use service insteon_plm.load_aldb first') | ||
| return | ||
|
|
||
| _LOGGER.info('RecID In Use Mode HWM Group Address Data 1 Data 2 Data 3') | ||
| _LOGGER.info('----- ------ ---- --- ----- -------- ------ ------ ------') | ||
| for mem_addr in aldb: | ||
| rec = aldb[mem_addr] | ||
| # For now we write this to the log | ||
| # Roadmap is to create a configuration panel | ||
| in_use = 'Y' if rec.control_flags.is_in_use else 'N' | ||
| mode = 'C' if rec.control_flags.is_controller else 'R' | ||
| hwm = 'Y' if rec.control_flags.is_high_water_mark else 'N' | ||
| _LOGGER.info(' {:04x} {:s} {:s} {:s} {:3d} {:s}' | ||
| ' {:3d} {:3d} {:3d}'.format( | ||
| rec.mem_addr, in_use, mode, hwm, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. continuation line missing indentation or outdented |
||
| rec.group, rec.address.human, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. continuation line missing indentation or outdented |
||
| rec.data1, rec.data2, rec.data3)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. continuation line missing indentation or outdented |
||
|
|
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line at end of file |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| add_all_link: | ||
| description: Tells the Insteom Modem (IM) start All-Linking mode. Once the the IM is in All-Linking mode, press the link button on the device to complete All-Linking. | ||
| fields: | ||
| group: | ||
| description: All-Link group number. | ||
| example: 1 | ||
| mode: | ||
| description: Linking mode controller - IM is controller responder - IM is responder | ||
| example: 'controller' | ||
| delete_all_link: | ||
| description: Tells the Insteon Modem (IM) to remove an All-Link record from the All-Link Database of the IM and a device. Once the IM is set to delete the link, press the link button on the corresponding device to complete the process. | ||
| fields: | ||
| group: | ||
| description: All-Link group number. | ||
| example: 1 | ||
| load_all_link_database: | ||
| description: Load the All-Link Database for a device. WARNING - Loading a device All-LInk database is very time consuming and inconsistant. This may take a LONG time and may need to be repeated to obtain all records. | ||
| fields: | ||
| entity_id: | ||
| description: Name of the device to print | ||
| example: 'light.1a2b3c' | ||
| reload: | ||
| description: Reload all records. If Y the current records are cleared from memory (does not effect the device) and the records are reloaded. If N the existing records are left in place and only missing records are added. Default is N. | ||
| example: N | ||
| print_all_link_database: | ||
| description: Print the All-Link Database for a device. Requires that the All-Link Database is loaded into memory. | ||
| fields: | ||
| entity_id: | ||
| description: Name of the device to print | ||
| example: 'light.1a2b3c' | ||
| print_im_all_link_database: | ||
| description: Print the All-Link Database for the INSTEON Modem (IM). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
continuation line missing indentation or outdented
unexpected spaces around keyword / parameter equals