From 01734108d4438f907bf4b5ec0d75debe48d0ee63 Mon Sep 17 00:00:00 2001 From: RodPayne Date: Tue, 4 Jun 2024 15:29:40 -0600 Subject: [PATCH] Initial coding for CONF_SHOW_ZONE_WHEN_AWAY. --- README.md | 4 +- custom_components/person_location/__init__.py | 2 +- custom_components/person_location/const.py | 2 +- .../person_location/manifest.json | 2 +- .../person_location/process_trigger.py | 49 ++++++++++++++----- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index fab436b..afe7072 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,9 @@ When a person is detected as moving between `Home` and `Away`, instead of going ![Person State Diagram](docs/images/PersonHomeState.png) -*Inspired by * +*Inspired by * + +If `CONF_SHOW_ZONE_WHEN_AWAY`, then `` is reported instead of `Away`. ### **Reverse geocode the location and make distance calculations** The custom integration supplies a service to reverse geocode the location (making it human readable) using `Open Street Map`, `MapQuest`, or `Google Maps` and calculate the distance from home (miles and minutes) using `WazeRouteCalculator`. diff --git a/custom_components/person_location/__init__.py b/custom_components/person_location/__init__.py index fdce86a..1fcae2a 100644 --- a/custom_components/person_location/__init__.py +++ b/custom_components/person_location/__init__.py @@ -137,7 +137,7 @@ def _handle_device_tracker_state_change(entity_id, old_state, new_state): _LOGGER.debug("[_handle_device_tracker_state_change]" + " === Start ===") _LOGGER.debug("[_handle_device_tracker_state_change]" + " (%s) " % (entity_id)) - if hasattr('old_state', 'state'): + if hasattr(old_state, 'state'): fromState = old_state.state else: fromState = 'unknown' diff --git a/custom_components/person_location/const.py b/custom_components/person_location/const.py index a266d47..713b193 100644 --- a/custom_components/person_location/const.py +++ b/custom_components/person_location/const.py @@ -29,7 +29,7 @@ API_STATE_OBJECT = DOMAIN + "." + DOMAIN + "_integration" INTEGRATION_NAME = "Person Location" ISSUE_URL = "https://github.com/rodpayne/home-assistant_person_location/issues" -VERSION = "2024.06.03" +VERSION = "2024.06.04" # Constants: METERS_PER_KM = 1000 diff --git a/custom_components/person_location/manifest.json b/custom_components/person_location/manifest.json index bed15af..5bfb242 100644 --- a/custom_components/person_location/manifest.json +++ b/custom_components/person_location/manifest.json @@ -20,5 +20,5 @@ "iot_class": "calculated", "issue_tracker": "https://github.com/rodpayne/home-assistant_person_location/issues", "requirements": [], - "version": "2024.06.03" + "version": "2024.06.04" } \ No newline at end of file diff --git a/custom_components/person_location/process_trigger.py b/custom_components/person_location/process_trigger.py index 9e3caeb..80c1a73 100644 --- a/custom_components/person_location/process_trigger.py +++ b/custom_components/person_location/process_trigger.py @@ -36,6 +36,7 @@ CONF_HOURS_EXTENDED_AWAY, CONF_MINUTES_JUST_ARRIVED, CONF_MINUTES_JUST_LEFT, + CONF_SHOW_ZONE_WHEN_AWAY, DOMAIN, PERSON_LOCATION_ENTITY, TARGET_LOCK, @@ -105,13 +106,27 @@ def handle_delayed_state_change( target.attributes[ATTR_COMPASS_BEARING] = 0 target.attributes[ATTR_DIRECTION] = "home" elif to_state == "Away": - change_state_later( - target.entity_id, - "Away", - "Extended Away", - (pli.configuration[CONF_HOURS_EXTENDED_AWAY] * 60), - ) - pass + if pli.configuration[CONF_SHOW_ZONE_WHEN_AWAY]: + reportedZone = target.attributes["zone"] + zoneStateObject = pli.hass.states.get("zone." + reportedZone) + if (zoneStateObject is None + or reportedZone.lower().endswith("stationary")): + _LOGGER.debug(f"Skipping use of zone {reportedZone} for Away state") + pass + else: + zoneAttributesObject \ + = zoneStateObject.attributes.copy() + if "friendly_name" in zoneAttributesObject: + target.state = zoneAttributesObject["friendly_name"] + if pli.configuration[ + CONF_HOURS_EXTENDED_AWAY] != 0: + change_state_later( + target.entity_id, + target.state, + "Extended Away", + (pli.configuration[CONF_HOURS_EXTENDED_AWAY] * 60), + ) + pass elif to_state == "Extended Away": pass @@ -150,11 +165,6 @@ def utc2local_naive(utc_dt): if str(local)[-6] == "-" or str(local)[-6] == "+": local = str(local)[:-6] # remove offset to make it offset-naive local = datetime.strptime(local, "%Y-%m-%d %H:%M:%S.%f") - _LOGGER.debug( - "[utc2local_naive] utc = %s; local = %s", - utc_dt, - local, - ) return local def handle_process_trigger(call): @@ -171,6 +181,7 @@ def handle_process_trigger(call): Attributes: - selected attributes from the triggered device tracker - state: "Just Arrived", "Home", "Just Left", "Away", or "Extended Away" + If CONF_SHOW_ZONE_WHEN_AWAY, then is reported instead of "Away". - person_name: - source: entity_id of the device tracker that triggered the automation - reported_state: the state reported by device tracker = "Home", "Away", or @@ -555,11 +566,23 @@ def handle_process_trigger(call): call_rest_command_service( trigger.personName, newTargetState ) + if newTargetState == "Away" and pli.configuration[CONF_SHOW_ZONE_WHEN_AWAY]: + # Get the state from the zone friendly_name: + if (zoneStateObject is None + or reportedZone.lower().endswith("stationary")): + # Skip stray zone names: + pass + else: + zoneAttributesObject \ + = zoneStateObject.attributes.copy() + if "friendly_name" in zoneAttributesObject: + newTargetState = zoneAttributesObject["friendly_name"] + + target.state = newTargetState if ha_just_started: target.attributes[ATTR_BREAD_CRUMBS] = newTargetState - target.state = newTargetState target.attributes["version"] = f"{DOMAIN} {VERSION}" target.set_state()