async def async_connect(self, session, url): import iota async with session.ws_connect(url) as ws: for listener in self._listener_states.values(): await self.subscribe(ws, listener) while True: listener_id, listener, bundle_hash, data = await self.get_next_message( ws) payload_json = data['payload'] payload_json = iota.TryteString(payload_json).encode() payload = json.loads(payload_json) self._hass.bus.fire( EVENT_ACTION_TRIGGERED, { ATTR_ROOT: listener[ATTR_ROOT], ATTR_BUNDLE: bundle_hash, ATTR_PAYLOAD: payload }) await self.unsubscribe(ws, listener_id) listener[ATTR_NEXT_ROOT] = data['next_root'] await self.subscribe(ws, listener) # update iota_mam_listeners.yaml with open(self._hass.config.path(YAML_LISTENER_STATES), 'w') as out: out.write(dump(self._listener_states))
def _write(path, data): """Write YAML helper.""" # Do it before opening file. If dump causes error it will now not # truncate the file. data = dump(data) with open(path, 'w', encoding='utf-8') as outfile: outfile.write(data)
def update_state_file(self): yaml = {} if os.path.isfile(self.yaml_path): yaml = load_yaml_config_file(self.yaml_path) yaml[self._seed] = self._state with open(self.yaml_path, 'w') as out: out.write(dump(yaml))
def _check_deprecated_turn_off(hass, turn_off_action): """Create an equivalent script for old turn off actions.""" if isinstance(turn_off_action, str): method = DEPRECATED_TURN_OFF_ACTIONS[turn_off_action] new_config = OrderedDict([ ("service", f"{DOMAIN}.{SERVICE_CALL_METHOD}"), ( "data_template", OrderedDict([("entity_id", "{{ entity_id }}"), ("method", method)]), ), ]) example_conf = dump(OrderedDict([(CONF_TURN_OFF_ACTION, new_config)])) _LOGGER.warning( "The '%s' action for turn off Kodi is deprecated and " "will cease to function in a future release. You need to " "change it for a generic Home Assistant script sequence, " "which is, for this turn_off action, like this:\n%s", turn_off_action, example_conf, ) new_config["data_template"] = OrderedDict([ (key, Template(value, hass)) for key, value in new_config["data_template"].items() ]) turn_off_action = [new_config] return turn_off_action
def update_ip_bans_config(path: str, ip_ban: IpBan): """Update config file with new banned IP address.""" with open(path, 'a') as out: ip_ = {str(ip_ban.ip_address): { ATTR_BANNED_AT: ip_ban.banned_at.strftime("%Y-%m-%dT%H:%M:%S") }} out.write('\n') out.write(dump(ip_))
def update_ip_bans_config(path: str, ip_ban: IpBan) -> None: """Update config file with new banned IP address.""" with open(path, "a") as out: ip_ = { str(ip_ban.ip_address): { ATTR_BANNED_AT: ip_ban.banned_at.isoformat() } } out.write("\n") out.write(yaml.dump(ip_))
def _add_ban(self, ip_ban: IpBan) -> None: """Update config file with new banned IP address.""" with open(self.path, "a", encoding="utf8") as out: ip_ = { str(ip_ban.ip_address): { ATTR_BANNED_AT: ip_ban.banned_at.isoformat() } } # Write in a single write call to avoid interleaved writes out.write("\n" + yaml.dump(ip_))
def update_config(path: str, dev_id: str, device: Device): """Add device to YAML configuration file.""" with open(path, 'a') as out: device = {device.dev_id: { 'name': device.name, 'mac': device.mac, 'picture': device.config_picture, 'track': device.track, CONF_AWAY_HIDE: device.away_hide }} out.write('\n') out.write(dump(device))
def update_config(path: str, dev_id: str, device: Device): """Add device to YAML configuration file.""" with open(path, 'a') as out: device = {device.dev_id: { ATTR_NAME: device.name, ATTR_MAC: device.mac, ATTR_ICON: device.icon, 'picture': device.config_picture, 'track': device.track, CONF_AWAY_HIDE: device.away_hide, 'vendor': device.vendor, }} out.write('\n') out.write(dump(device))
def update_config(path: str, dev_id: str, device: Device) -> None: """Add device to YAML configuration file.""" with open(path, "a", encoding="utf8") as out: device_config = { device.dev_id: { ATTR_NAME: device.name, ATTR_MAC: device.mac, ATTR_ICON: device.icon, "picture": device.config_picture, "track": device.track, } } out.write("\n") out.write(dump(device_config))
def update_config(path: str, dev_id: str, device: Device): """Add device to YAML configuration file.""" with open(path, "a") as out: device = { device.dev_id: { ATTR_NAME: device.name, ATTR_MAC: device.mac, ATTR_ICON: device.icon, "picture": device.config_picture, "track": device.track, CONF_AWAY_HIDE: device.away_hide, } } out.write("\n") out.write(dump(device))
def _test_selector( selector_type, schema, valid_selections, invalid_selections, converter=None ): """Help test a selector.""" def default_converter(x): return x if converter is None: converter = default_converter # Validate selector configuration config = {selector_type: schema} selector.validate_selector(config) selector_instance = selector.selector(config) # We do not allow enums in the config, as they cannot serialize assert not any(isinstance(val, Enum) for val in selector_instance.config.values()) # Use selector in schema and validate vol_schema = vol.Schema({"selection": selector_instance}) for selection in valid_selections: assert vol_schema({"selection": selection}) == { "selection": converter(selection) } for selection in invalid_selections: with pytest.raises(vol.Invalid): vol_schema({"selection": selection}) # Serialize selector selector_instance = selector.selector({selector_type: schema}) assert ( selector.selector(selector_instance.serialize()["selector"]).config == selector_instance.config ) # Test serialized selector can be dumped to YAML yaml.dump(selector_instance.serialize())
def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Hue lights.""" if discovery_info is None or 'bridge_id' not in discovery_info: return if config is not None and len(config) > 0: # Legacy configuration, will be removed in 0.60 config_str = yaml.dump([config]) # Indent so it renders in a fixed-width font config_str = re.sub('(?m)^', ' ', config_str) hass.components.persistent_notification.async_create( MIGRATION_INSTRUCTIONS.format(config=config_str), title=MIGRATION_TITLE, notification_id=MIGRATION_ID) bridge_id = discovery_info['bridge_id'] bridge = hass.data[hue.DOMAIN][bridge_id] unthrottled_update_lights(hass, bridge, add_devices)
def update_config(path: str, dev_id: str, device: JablotronSensor): """Add device to YAML configuration file.""" with open(path, 'a') as out: device = { device.dev_id: { 'dev_id': device.dev_id, # ATTR_NAME: device._name, # ATTR_MAC: sensor.mac, # ATTR_ICON: sensor.icon, # 'picture': sensor.config_picture, # 'track': sensor.track, # CONF_AWAY_HIDE: sensor.away_hide, } } out.write('\n') out.write(dump(device)) _LOGGER.debug('update_config(): updated %s with sensor %s', path, dev_id)
def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Hue lights.""" if discovery_info is None or 'bridge_id' not in discovery_info: return if config is not None and config: # Legacy configuration, will be removed in 0.60 config_str = yaml.dump([config]) # Indent so it renders in a fixed-width font config_str = re.sub('(?m)^', ' ', config_str) hass.components.persistent_notification.async_create( MIGRATION_INSTRUCTIONS.format(config=config_str), title=MIGRATION_TITLE, notification_id=MIGRATION_ID) bridge_id = discovery_info['bridge_id'] bridge = hass.data[hue.DOMAIN][bridge_id] unthrottled_update_lights(hass, bridge, add_devices)
async def test_update_config_write_to_temp_file(hass, hass_client, tmpdir): """Test config with a temp file.""" test_dir = await hass.async_add_executor_job(tmpdir.mkdir, "files") group_yaml = Path(test_dir / "group.yaml") with patch.object(group, "GROUP_CONFIG_PATH", group_yaml), patch.object( config, "SECTIONS", ["group"] ): await async_setup_component(hass, "config", {}) client = await hass_client() orig_data = { "hello.beer": {"ignored": True}, "other.entity": {"polling_intensity": 2}, } contents = dump(orig_data) await hass.async_add_executor_job(write_utf8_file, group_yaml, contents) mock_call = AsyncMock() with patch.object(hass.services, "async_call", mock_call): resp = await client.post( "/api/config/group/config/hello_beer", data=json.dumps( {"name": "Beer", "entities": ["light.top", "light.bottom"]} ), ) await hass.async_block_till_done() assert resp.status == HTTPStatus.OK result = await resp.json() assert result == {"result": "ok"} new_data = await hass.async_add_executor_job(load_yaml, group_yaml) assert new_data == { **orig_data, "hello_beer": { "name": "Beer", "entities": ["light.top", "light.bottom"], }, } mock_call.assert_called_once_with("group", "reload")
def _check_deprecated_turn_off(hass, turn_off_action): """Create an equivalent script for old turn off actions.""" if isinstance(turn_off_action, str): method = DEPRECATED_TURN_OFF_ACTIONS[turn_off_action] new_config = OrderedDict( [('service', '{}.{}'.format(DOMAIN, SERVICE_CALL_METHOD)), ('data_template', OrderedDict( [('entity_id', '{{ entity_id }}'), ('method', method)]))]) example_conf = dump(OrderedDict( [(CONF_TURN_OFF_ACTION, new_config)])) _LOGGER.warning( "The '%s' action for turn off Kodi is deprecated and " "will cease to function in a future release. You need to " "change it for a generic Home Assistant script sequence, " "which is, for this turn_off action, like this:\n%s", turn_off_action, example_conf) new_config['data_template'] = OrderedDict( [(key, Template(value, hass)) for key, value in new_config['data_template'].items()]) turn_off_action = [new_config] return turn_off_action
def test_dump_unicode(): """The that the dump method returns empty None values.""" assert yaml.dump({"a": None, "b": "привет"}) == "a:\nb: привет\n"
def test_dump(): """The that the dump method returns empty None values.""" assert yaml.dump({"a": None, "b": "b"}) == "a:\nb: b\n"
def test_dump(self): """The that the dump method returns empty None values.""" assert yaml.dump({"a": None, "b": "b"}) == "a:\nb: b\n"
def test_dump(self): """The that the dump method returns empty None values.""" assert yaml.dump({'a': None, 'b': 'b'}) == 'a:\nb: b\n'
def test_input(): """Test loading inputs.""" data = {"hello": yaml.Input("test_name")} assert yaml.parse_yaml(yaml.dump(data)) == data
def test_placeholder(): """Test loading placeholders.""" data = {"hello": yaml.Placeholder("test_name")} assert yaml.parse_yaml(yaml.dump(data)) == data
def yaml(self) -> str: """Dump blueprint as YAML.""" return yaml.dump(self.data)
def mock_write(path, data): """Mock writing data.""" data = dump(data) written.append(data)
def test_dump_unicode(self): """The that the dump method returns empty None values.""" assert yaml.dump({'a': None, 'b': 'привет'}) == 'a:\nb: привет\n'
def test_input(try_both_loaders, try_both_dumpers): """Test loading inputs.""" data = {"hello": yaml.Input("test_name")} assert yaml.parse_yaml(yaml.dump(data)) == data
def test_representing_yaml_loaded_data(): """Test we can represent YAML loaded data.""" files = {YAML_CONFIG_FILE: 'key: [1, "2", 3]'} with patch_yaml_files(files): data = load_yaml_config_file(YAML_CONFIG_FILE) assert yaml.dump(data) == "key:\n- 1\n- '2'\n- 3\n"
def _write(self, path, data): """Write YAML helper.""" data = dump(data) with open(path, 'w', encoding='utf-8') as outfile: outfile.write(data)
def _write(path, data): """Write YAML helper.""" # Do it before opening file. If dump causes error it will now not # truncate the file. contents = dump(data) write_utf8_file_atomic(path, contents)
def main(): global GROUP_CONFIG logging.basicConfig(level=logging.INFO) try: from colorlog import ColoredFormatter logging.getLogger().handlers[0].setFormatter( ColoredFormatter("%(log_color)s%(levelname)s %(message)s%(reset)s", datefmt="", reset=True, log_colors={ 'DEBUG': 'cyan', 'INFO': 'green', 'WARNING': 'yellow', 'ERROR': 'red', 'CRITICAL': 'red', })) except ImportError: pass parser = argparse.ArgumentParser( description="Check Home Assistant configuration.") parser.add_argument( '-c', '--config', default=get_default_config_dir(), help="Directory that contains the Home Assistant configuration") args = parser.parse_args() config_dir = os.path.join(os.getcwd(), args.config) hass = homeassistant.core.HomeAssistant() hass.config.config_dir = config_dir config_path = find_config_file(config_dir) config = load_yaml_config_file(config_path) GROUP_CONFIG = config['group'] name = config['homeassistant'].get('name', 'Home') lovelace = OrderedDict() lovelace['name'] = name views = lovelace['views'] = [] if 'default_view' in GROUP_CONFIG: views.append(convert_view(GROUP_CONFIG['default_view'], 'default_view')) for name, conf in GROUP_CONFIG.items(): if name == 'default_view': continue if not conf.get('view', False): continue views.append(convert_view(conf, name)) views.append({ 'name': "All Entities", 'tab_icon': "mdi:settings", 'cards': [{ 'type': 'entity-filter', 'filter': [{}], 'card_config': { 'title': 'All Entities' } }], }) lovelace_path = os.path.join(config_dir, 'ui-lovelace.yaml') if os.path.exists(lovelace_path): i = 0 while os.path.exists(lovelace_path + '.bkp.{}'.format(i)): i += 1 bkp_path = lovelace_path + '.bkp.{}'.format(i) shutil.move(lovelace_path, bkp_path) _LOGGER.error( "The lovelace configuration already exists under %s! " "I will move it to %s", lovelace_path, bkp_path) with open(lovelace_path, 'w', encoding='utf-8') as f: f.write(yaml.dump(lovelace) + '\n') _LOGGER.info("Successfully migrated lovelace configuration to %s", lovelace_path) return 0