diff --git a/custom_components/variable/__init__.py b/custom_components/variable/__init__.py index 322514a..9104f92 100644 --- a/custom_components/variable/__init__.py +++ b/custom_components/variable/__init__.py @@ -33,13 +33,13 @@ DEFAULT_REPLACE_ATTRIBUTES, DOMAIN, PLATFORMS, + SERVICE_UPDATE_SENSOR, ) _LOGGER = logging.getLogger(__name__) SERVICE_SET_VARIABLE_LEGACY = "set_variable" SERVICE_SET_ENTITY_LEGACY = "set_entity" -SERVICE_UPDATE_SENSOR = "update_sensor" SERVICE_SET_VARIABLE_LEGACY_SCHEMA = vol.Schema( { diff --git a/custom_components/variable/config_flow.py b/custom_components/variable/config_flow.py index 20c0a12..b679cea 100644 --- a/custom_components/variable/config_flow.py +++ b/custom_components/variable/config_flow.py @@ -15,20 +15,26 @@ ATTR_LATITUDE, ATTR_LONGITUDE, CONF_DEVICE_CLASS, + CONF_ENTITY_ID, CONF_ICON, CONF_NAME, CONF_UNIT_OF_MEASUREMENT, + STATE_OFF, + STATE_ON, Platform, ) from homeassistant.core import HomeAssistant, callback from homeassistant.data_entry_flow import FlowResult -from homeassistant.helpers import selector -import homeassistant.helpers.config_validation as cv +from homeassistant.helpers import config_validation as cv, entity_registry, selector import homeassistant.util.dt as dt_util from iso4217 import Currency import voluptuous as vol from .const import ( + ATTR_ATTRIBUTES, + ATTR_DELETE_LOCATION_NAME, + ATTR_REPLACE_ATTRIBUTES, + ATTR_VALUE, CONF_ATTRIBUTES, CONF_ENTITY_PLATFORM, CONF_EXCLUDE_FROM_RECORDER, @@ -47,6 +53,9 @@ DEFAULT_RESTORE, DOMAIN, PLATFORMS, + SERVICE_UPDATE_BINARY_SENSOR, + SERVICE_UPDATE_DEVICE_TRACKER, + SERVICE_UPDATE_SENSOR, ) from .helpers import value_to_type @@ -573,21 +582,522 @@ async def async_step_init( ) -> FlowResult: """Manage the options.""" - if not self.config_entry.data.get(CONF_YAML_VARIABLE): - if self.config_entry.data.get(CONF_ENTITY_PLATFORM) in PLATFORMS and ( - new_func := getattr( - self, - "async_step_" - + self.config_entry.data.get(CONF_ENTITY_PLATFORM) - + "_options", - False, - ) - ): - return await new_func() - else: + if self.config_entry.data.get(CONF_YAML_VARIABLE): _LOGGER.debug("[YAML] No Options for YAML Created Variables") return self.async_abort(reason="yaml_variable") + if self.config_entry.data.get(CONF_ENTITY_PLATFORM) in PLATFORMS: + change_value = ( + "change_" + self.config_entry.data.get(CONF_ENTITY_PLATFORM) + "_value" + ) + change_options = ( + self.config_entry.data.get(CONF_ENTITY_PLATFORM) + "_options" + ) + return self.async_show_menu( + step_id="init", + menu_options=[change_value, change_options], + ) + return False + + async def async_step_change_sensor_value( + self, user_input=None, errors=None + ) -> FlowResult: + errors = {} + ent = entity_registry.async_entries_for_config_entry( + entity_registry.async_get(self.hass), self.config_entry.entry_id + ) + if len(ent) > 0: + entity_id = ent[0].entity_id + state = self.hass.states.get(entity_id) + else: + _LOGGER.error("Unable to load Variable to Change Value") + _LOGGER.debug(f"[Change Sensor Value] entity_id: {entity_id}") + _LOGGER.debug(f"[Change Sensor Value] state: {state}") + if user_input is not None: + _LOGGER.debug(f"[Change Sensor Value] user_input: {user_input}") + if ( + user_input.get(CONF_VALUE) is not None + and isinstance(user_input.get(CONF_VALUE), str) + and self.config_entry.data.get(CONF_VALUE_TYPE) == "datetime" + ): + if ( + user_input.get(CONF_TZOFFSET) is not None + and re.match( + r"^[+-]?\d\d\:?\d\d\s*$", user_input.get(CONF_TZOFFSET) + ) + is not None + ): + val = user_input.get(CONF_VALUE) + user_input.get(CONF_TZOFFSET) + else: + val = user_input.get(CONF_VALUE) + "+0000" + else: + val = user_input.get(CONF_VALUE) + _LOGGER.debug(f"[Change Sensor Value] val: {val}") + try: + newval = value_to_type( + val, + self.config_entry.data.get(CONF_VALUE_TYPE), + ) + except ValueError: + errors["base"] = "invalid_value_type" + else: + user_input[CONF_VALUE] = newval + + if not errors: + update_variable = { + CONF_ENTITY_ID: [entity_id], + ATTR_REPLACE_ATTRIBUTES: True, + } + update_variable.update({ATTR_VALUE: val}) + update_variable.update( + {ATTR_ATTRIBUTES: user_input.get(ATTR_ATTRIBUTES)} + ) + _LOGGER.debug( + f"[Change Sensor Value] update_variable: {update_variable}" + ) + await self.hass.services.async_call( + DOMAIN, SERVICE_UPDATE_SENSOR, service_data=update_variable + ) + return self.async_abort(reason="value_changed") + + CHANGE_SENSOR_VALUE_SCHEMA = self.build_change_sensor_value(state) + + if self.config_entry.data.get(CONF_NAME) is None or self.config_entry.data.get( + CONF_NAME + ) == self.config_entry.data.get(CONF_VARIABLE_ID): + disp_name = self.config_entry.data.get(CONF_VARIABLE_ID) + else: + disp_name = f"{self.config_entry.data.get(CONF_NAME)} ({self.config_entry.data.get(CONF_VARIABLE_ID)})" + + return self.async_show_form( + step_id="change_sensor_value", + data_schema=CHANGE_SENSOR_VALUE_SCHEMA, + errors=errors, + description_placeholders={ + "disp_name": disp_name, + }, + ) + + def build_change_sensor_value(self, state): + CHANGE_VARIABLE_VALUE_SCHEMA = vol.Schema({}) + if self.config_entry.data.get(CONF_DEVICE_CLASS) in [ + sensor.SensorDeviceClass.DATE + ]: + if state.state: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_VALUE, + default=state.state, + ): selector.DateSelector(selector.DateSelectorConfig()) + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_VALUE, + ): selector.DateSelector(selector.DateSelectorConfig()) + } + ) + + elif self.config_entry.data.get(CONF_DEVICE_CLASS) in [ + sensor.SensorDeviceClass.TIMESTAMP + ]: + if state.state: + dt = value_to_type( + state.state, self.config_entry.data.get(CONF_VALUE_TYPE) + ) + if dt is not None and isinstance(dt, datetime.datetime): + tz_offset = dt.strftime("%z") + if tz_offset is None: + tz_offset = "+0000" + ts_val = dt.strftime("%Y-%m-%d %H:%M:%S") + else: + ts_val = None + tz_offset = "+0000" + _LOGGER.debug(f"ts_val: {ts_val}") + _LOGGER.debug(f"tz_offset: {tz_offset}") + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_VALUE, + default=ts_val, + ): selector.DateTimeSelector(selector.DateTimeSelectorConfig()), + vol.Optional( + CONF_TZOFFSET, + default=tz_offset, + ): selector.TextSelector(selector.TextSelectorConfig()), + } + ) + else: + DEFAULT_TZOFFSET = datetime.datetime.now( + dt_util.get_time_zone(self.hass.config.time_zone) + ).strftime("%z") + if DEFAULT_TZOFFSET is None: + DEFAULT_TZOFFSET = "+0000" + _LOGGER.debug(f"DEFAULT_TZOFFSET: {DEFAULT_TZOFFSET}") + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_VALUE, + ): selector.DateTimeSelector(selector.DateTimeSelectorConfig()), + vol.Optional( + CONF_TZOFFSET, + default=DEFAULT_TZOFFSET, + ): selector.TextSelector(selector.TextSelectorConfig()), + } + ) + else: + if state.state: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_VALUE, + default=str(state.state), + ): selector.TextSelector(selector.TextSelectorConfig()) + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_VALUE, + ): selector.TextSelector(selector.TextSelectorConfig()) + } + ) + if state.as_dict().get("attributes"): + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_ATTRIBUTES, default=state.as_dict().get("attributes") + ): selector.ObjectSelector(selector.ObjectSelectorConfig()) + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional(CONF_ATTRIBUTES): selector.ObjectSelector( + selector.ObjectSelectorConfig() + ) + } + ) + return CHANGE_VARIABLE_VALUE_SCHEMA + + async def async_step_change_binary_sensor_value( + self, user_input=None, errors=None + ) -> FlowResult: + errors = {} + ent = entity_registry.async_entries_for_config_entry( + entity_registry.async_get(self.hass), self.config_entry.entry_id + ) + if len(ent) > 0: + entity_id = ent[0].entity_id + state = self.hass.states.get(entity_id) + else: + _LOGGER.error("Unable to load Variable to Change Value") + _LOGGER.debug(f"[Change Binary Sensor Value] entity_id: {entity_id}") + _LOGGER.debug(f"[Change Binary Sensor Value] state: {state}") + if user_input is not None: + _LOGGER.debug(f"[Change Binary Sensor Value] user_input: {user_input}") + + if not errors: + update_variable = { + CONF_ENTITY_ID: [entity_id], + ATTR_REPLACE_ATTRIBUTES: True, + } + update_variable.update({ATTR_VALUE: user_input.get(CONF_VALUE)}) + update_variable.update( + {ATTR_ATTRIBUTES: user_input.get(ATTR_ATTRIBUTES)} + ) + _LOGGER.debug( + f"[Change Binary Sensor Value] update_variable: {update_variable}" + ) + await self.hass.services.async_call( + DOMAIN, SERVICE_UPDATE_BINARY_SENSOR, service_data=update_variable + ) + return self.async_abort(reason="value_changed") + + CHANGE_BINARY_SENSOR_VALUE_SCHEMA = self.build_change_binary_sensor_value(state) + + if self.config_entry.data.get(CONF_NAME) is None or self.config_entry.data.get( + CONF_NAME + ) == self.config_entry.data.get(CONF_VARIABLE_ID): + disp_name = self.config_entry.data.get(CONF_VARIABLE_ID) + else: + disp_name = f"{self.config_entry.data.get(CONF_NAME)} ({self.config_entry.data.get(CONF_VARIABLE_ID)})" + + return self.async_show_form( + step_id="change_binary_sensor_value", + data_schema=CHANGE_BINARY_SENSOR_VALUE_SCHEMA, + errors=errors, + description_placeholders={ + "disp_name": disp_name, + }, + ) + + def build_change_binary_sensor_value(self, state): + if state.state is None or ( + isinstance(state.state, str) + and state.state.lower() in ["", "none", "unknown", "unavailable"] + ): + bistate = "None" + elif state.state == STATE_OFF: + bistate = "false" + elif state.state == STATE_ON: + bistate = "true" + else: + bistate = state.state + CHANGE_VARIABLE_VALUE_SCHEMA = vol.Schema( + { + vol.Optional( + CONF_VALUE, + default=bistate, + ): selector.SelectSelector( + selector.SelectSelectorConfig( + options=["None", "true", "false"], + translation_key="boolean_options", + multiple=False, + custom_value=False, + mode=selector.SelectSelectorMode.LIST, + ) + ) + } + ) + if state.as_dict().get("attributes"): + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_ATTRIBUTES, default=state.as_dict().get("attributes") + ): selector.ObjectSelector(selector.ObjectSelectorConfig()) + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional(CONF_ATTRIBUTES): selector.ObjectSelector( + selector.ObjectSelectorConfig() + ) + } + ) + return CHANGE_VARIABLE_VALUE_SCHEMA + + async def async_step_change_device_tracker_value( + self, user_input=None, errors=None + ) -> FlowResult: + errors = {} + ent = entity_registry.async_entries_for_config_entry( + entity_registry.async_get(self.hass), self.config_entry.entry_id + ) + if len(ent) > 0: + entity_id = ent[0].entity_id + state = self.hass.states.get(entity_id) + else: + _LOGGER.error("Unable to load Variable to Change Value") + _LOGGER.debug(f"[Change Device Tracker Value] entity_id: {entity_id}") + _LOGGER.debug(f"[Change Device Tracker Value] state: {state}") + if user_input is not None: + _LOGGER.debug(f"[Change Device Tracker Value] user_input: {user_input}") + + if not errors: + update_variable = { + CONF_ENTITY_ID: [entity_id], + ATTR_REPLACE_ATTRIBUTES: True, + } + if user_input.get(ATTR_LATITUDE): + update_variable.update( + {ATTR_LATITUDE: user_input.get(ATTR_LATITUDE)} + ) + if user_input.get(ATTR_LONGITUDE): + update_variable.update( + {ATTR_LONGITUDE: user_input.get(ATTR_LONGITUDE)} + ) + if user_input.get(ATTR_LOCATION_NAME): + update_variable.update( + {ATTR_LOCATION_NAME: user_input.get(ATTR_LOCATION_NAME)} + ) + if user_input.get(ATTR_DELETE_LOCATION_NAME): + update_variable.update( + { + ATTR_DELETE_LOCATION_NAME: user_input.get( + ATTR_DELETE_LOCATION_NAME + ) + } + ) + if user_input.get(ATTR_GPS_ACCURACY): + update_variable.update( + {ATTR_GPS_ACCURACY: user_input.get(ATTR_GPS_ACCURACY)} + ) + if user_input.get(ATTR_BATTERY_LEVEL): + update_variable.update( + {ATTR_BATTERY_LEVEL: user_input.get(ATTR_BATTERY_LEVEL)} + ) + update_variable.update( + {ATTR_ATTRIBUTES: user_input.get(ATTR_ATTRIBUTES)} + ) + _LOGGER.debug( + f"[Change Device Tracker Value] update_variable: {update_variable}" + ) + await self.hass.services.async_call( + DOMAIN, SERVICE_UPDATE_DEVICE_TRACKER, service_data=update_variable + ) + return self.async_abort(reason="value_changed") + + CHANGE_DEVICE_TRACKER_VALUE_SCHEMA = self.build_change_device_tracker_value( + state + ) + + if self.config_entry.data.get(CONF_NAME) is None or self.config_entry.data.get( + CONF_NAME + ) == self.config_entry.data.get(CONF_VARIABLE_ID): + disp_name = self.config_entry.data.get(CONF_VARIABLE_ID) + else: + disp_name = f"{self.config_entry.data.get(CONF_NAME)} ({self.config_entry.data.get(CONF_VARIABLE_ID)})" + if state.state: + dt_state = state.state + else: + dt_state = "None" + + return self.async_show_form( + step_id="change_device_tracker_value", + data_schema=CHANGE_DEVICE_TRACKER_VALUE_SCHEMA, + errors=errors, + description_placeholders={"disp_name": disp_name, "dt_state": dt_state}, + ) + + def build_change_device_tracker_value(self, state): + attr = dict(state.as_dict().get("attributes")) + lat = attr.pop(ATTR_LATITUDE, None) + long = attr.pop(ATTR_LONGITUDE, None) + loc = attr.pop(ATTR_LOCATION_NAME, None) + gpsacc = attr.pop(ATTR_GPS_ACCURACY, None) + battlvl = attr.pop(ATTR_BATTERY_LEVEL, None) + CHANGE_VARIABLE_VALUE_SCHEMA = vol.Schema( + { + vol.Required(ATTR_LATITUDE, default=lat): selector.NumberSelector( + selector.NumberSelectorConfig( + min=-90, + max=90, + step="any", + unit_of_measurement="°", + mode=selector.NumberSelectorMode.BOX, + ) + ), + vol.Required(ATTR_LONGITUDE, default=long): selector.NumberSelector( + selector.NumberSelectorConfig( + min=-180, + max=180, + step="any", + unit_of_measurement="°", + mode=selector.NumberSelectorMode.BOX, + ) + ), + } + ) + if loc is None: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional(ATTR_LOCATION_NAME): cv.string, + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + ATTR_LOCATION_NAME, + default=loc, + ): cv.string, + } + ) + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + ATTR_DELETE_LOCATION_NAME, + ): selector.BooleanSelector(selector.BooleanSelectorConfig()) + } + ) + if gpsacc is None: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional(ATTR_GPS_ACCURACY): selector.NumberSelector( + selector.NumberSelectorConfig( + min=0, + max=1000000, + step=1, + unit_of_measurement="m", + mode=selector.NumberSelectorMode.BOX, + ) + ), + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + ATTR_GPS_ACCURACY, + default=gpsacc, + ): selector.NumberSelector( + selector.NumberSelectorConfig( + min=0, + max=1000000, + step=1, + unit_of_measurement="m", + mode=selector.NumberSelectorMode.BOX, + ) + ), + } + ) + if battlvl is None: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + ATTR_BATTERY_LEVEL, + ): selector.NumberSelector( + selector.NumberSelectorConfig( + min=0, + max=100, + step=1, + unit_of_measurement="%", + mode=selector.NumberSelectorMode.BOX, + ) + ), + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + ATTR_BATTERY_LEVEL, + default=battlvl, + ): selector.NumberSelector( + selector.NumberSelectorConfig( + min=0, + max=100, + step=1, + unit_of_measurement="%", + mode=selector.NumberSelectorMode.BOX, + ) + ), + } + ) + if attr: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional( + CONF_ATTRIBUTES, default=attr + ): selector.ObjectSelector(selector.ObjectSelectorConfig()) + } + ) + else: + CHANGE_VARIABLE_VALUE_SCHEMA = CHANGE_VARIABLE_VALUE_SCHEMA.extend( + { + vol.Optional(CONF_ATTRIBUTES): selector.ObjectSelector( + selector.ObjectSelectorConfig() + ) + } + ) + return CHANGE_VARIABLE_VALUE_SCHEMA + async def async_step_sensor_options( self, user_input=None, errors=None ) -> FlowResult: diff --git a/custom_components/variable/const.py b/custom_components/variable/const.py index 3221fff..dbda11d 100644 --- a/custom_components/variable/const.py +++ b/custom_components/variable/const.py @@ -37,3 +37,7 @@ ATTR_REPLACE_ATTRIBUTES = "replace_attributes" ATTR_VALUE = "value" ATTR_VARIABLE = "variable" + +SERVICE_UPDATE_SENSOR = "update_sensor" +SERVICE_UPDATE_BINARY_SENSOR = "update_binary_sensor" +SERVICE_UPDATE_DEVICE_TRACKER = "update_device_tracker" diff --git a/custom_components/variable/strings.json b/custom_components/variable/strings.json index a7126b9..2c12983 100644 --- a/custom_components/variable/strings.json +++ b/custom_components/variable/strings.json @@ -73,7 +73,16 @@ }, "options": { "step": { - "init": {}, + "init": { + "menu_options": { + "change_sensor_value": "Change Value and Attributes", + "change_binary_sensor_value": "Change Value and Attributes", + "change_device_tracker_value": "Change Value and Attributes", + "sensor_options": "Change Options", + "binary_sensor_options": "Change Options", + "device_tracker_options": "Change Options" + } + }, "sensor_options": { "title": "Variables+History - Sensor", "data": { @@ -95,6 +104,36 @@ }, "description": "Update existing Sensor Variable" }, + "change_sensor_value": { + "title": "Variables+History - Change Sensor Value", + "data": { + "value": "Value", + "tz_offset": "Time Zone Offset", + "attributes": "Attributes" + }, + "description": "Update existing Sensor Variable" + }, + "change_binary_sensor_value": { + "title": "Variables+History - Change Binary Sensor Value", + "data": { + "value": "Value", + "attributes": "Attributes" + }, + "description": "Update existing Binary Sensor Variable" + }, + "change_device_tracker_value": { + "title": "Variables+History - Device Tracker (GPS)", + "data": { + "latitude": "Latitude", + "longitude": "Longitude", + "location_name": "Location Name", + "delete_location_name": "Delete Location Name", + "gps_accuracy": "GPS Accuracy", + "battery_level": "Battery Level", + "attributes": "Attributes" + }, + "description": "Update existing Device Tracker (GPS) Variable" + }, "binary_sensor_options": { "title": "Variables+History - Binary Sensor", "data": { @@ -125,7 +164,8 @@ }, "abort": { "yaml_variable": "Cannot change options here for Variables created by YAML.\n\nTo use the User Interface to manage this Variable, you will need to:\n1. Remove it from YAML\n2. Restart Home Assistant\n3. Manually recreate it in Home Assistant, Integrations, +Add Integration.", - "yaml_update_error": "Unable to update YAML Sensor Variable" + "yaml_update_error": "Unable to update YAML Sensor Variable", + "value_changed": "Variable Changed" }, "error": { "invalid_value_type": "The value entered is not compatible with the selected device_class", diff --git a/custom_components/variable/translations/en.json b/custom_components/variable/translations/en.json index e50b334..d1741df 100644 --- a/custom_components/variable/translations/en.json +++ b/custom_components/variable/translations/en.json @@ -73,7 +73,16 @@ }, "options": { "step": { - "init": {}, + "init": { + "menu_options": { + "change_sensor_value": "Change Value and Attributes", + "change_binary_sensor_value": "Change Value and Attributes", + "change_device_tracker_value": "Change Value and Attributes", + "sensor_options": "Change Options", + "binary_sensor_options": "Change Options", + "device_tracker_options": "Change Options" + } + }, "sensor_options": { "title": "Variables+History - Sensor", "data": { @@ -95,6 +104,36 @@ }, "description": "Updating Sensor Variable Page 2\n\n**Variable: {disp_name}**\n**Device Class: {device_class}**\n**Value Type: {value_type}**" }, + "change_sensor_value": { + "title": "Variables+History - Change Sensor Value", + "data": { + "value": "Value", + "tz_offset": "Time Zone Offset", + "attributes": "Attributes" + }, + "description": "**Updating Sensor: {disp_name}**" + }, + "change_binary_sensor_value": { + "title": "Variables+History - Change Binary Sensor Value", + "data": { + "value": "Value", + "attributes": "Attributes" + }, + "description": "**Updating Binary Sensor: {disp_name}**" + }, + "change_device_tracker_value": { + "title": "Variables+History - Device Tracker (GPS)", + "data": { + "latitude": "Latitude", + "longitude": "Longitude", + "location_name": "Location Name", + "delete_location_name": "Delete Location Name", + "gps_accuracy": "GPS Accuracy", + "battery_level": "Battery Level", + "attributes": "Attributes" + }, + "description": "**Updating Device Tracker: {disp_name}**\n**Current State: {dt_state}**" + }, "binary_sensor_options": { "title": "Variables+History - Binary Sensor", "data": { @@ -125,7 +164,8 @@ }, "abort": { "yaml_variable": "Cannot change options here for Variables created by YAML.\n\nTo use the User Interface to manage this Variable, you will need to:\n1. Remove it from YAML\n2. Restart Home Assistant\n3. Manually recreate it in Home Assistant, Integrations, +Add Integration.", - "yaml_update_error": "Unable to update YAML Sensor Variable" + "yaml_update_error": "Unable to update YAML Sensor Variable", + "value_changed": "Variable Changed" }, "error": { "invalid_value_type": "The value entered is not compatible with the selected device_class: {device_class}. Expected {value_type}.",