From 724eea52ad0ee280efc6f4d0c04b8429035e3b82 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 6 Jul 2022 11:57:57 -0400 Subject: [PATCH 001/329] Update sensor.py Add Township and Municipality as additional options for City. Move from separate if statements to if-elif to stop once the first one that exists is found. --- custom_components/places/sensor.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 152117c4..bbb0ebbd 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -609,12 +609,18 @@ def do_update(self, reason): street_number = osm_decoded["address"]["house_number"] if "road" in osm_decoded["address"]: street = osm_decoded["address"]["road"] + if "city" in osm_decoded["address"]: city = osm_decoded["address"]["city"] - if "town" in osm_decoded["address"]: + elif "town" in osm_decoded["address"]: city = osm_decoded["address"]["town"] - if "village" in osm_decoded["address"]: + elif "village" in osm_decoded["address"]: city = osm_decoded["address"]["village"] + elif "township" in osm_decoded["address"]: + city = osm_decoded["address"]["township"] + elif "municipality" in osm_decoded["address"]: + city = osm_decoded["address"]["municipality"] + if "city_district" in osm_decoded["address"]: postal_town = osm_decoded["address"]["city_district"] if "suburb" in osm_decoded["address"]: From 9ca06ee57455b486eae1fb20828e9408ff26e35b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 6 Jul 2022 13:45:04 -0400 Subject: [PATCH 002/329] Add Hamlet to Neighbourhood Moves Neighbourhood out from below if place as I believe it should be outside of that if statement Will set Neighbourhood to Hamlet if Neighbourhood is undefined and Hamlet exists --- custom_components/places/sensor.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 152117c4..561e191b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -600,8 +600,6 @@ def do_update(self, reason): if "name:" + language in osm_decoded["namedetails"]: place_name = osm_decoded["namedetails"]["name:" + language] break - if "neighbourhood" in osm_decoded["address"]: - place_neighbourhood = osm_decoded["address"]["neighbourhood"] if self._devicetracker_zone == 'not_home' and place_name != 'house': new_state = place_name @@ -609,6 +607,12 @@ def do_update(self, reason): street_number = osm_decoded["address"]["house_number"] if "road" in osm_decoded["address"]: street = osm_decoded["address"]["road"] + + if "neighbourhood" in osm_decoded["address"]: + place_neighbourhood = osm_decoded["address"]["neighbourhood"] + elif "hamlet" in osm_decoded["address"]: + place_neighbourhood = osm_decoded["address"]["hamlet"] + if "city" in osm_decoded["address"]: city = osm_decoded["address"]["city"] if "town" in osm_decoded["address"]: From ad9f4cabee364d2a3a3c253e03058a96cdbd63e1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 7 Jul 2022 22:44:32 -0400 Subject: [PATCH 003/329] Add State Abbreviation Attribute Uses the ISO3166-2-lvl4 field to get the state or region abbreviation. --- custom_components/places/sensor.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 152117c4..a700b40e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -253,6 +253,7 @@ ATTR_POSTAL_TOWN = 'postal_town' ATTR_POSTAL_CODE = 'postal_code' ATTR_REGION = 'state_province' +ATTR_STATE_ABBR = 'state_abbr' ATTR_COUNTRY = 'country' ATTR_COUNTY = 'county' ATTR_FORMATTED_ADDRESS = 'formatted_address' @@ -344,6 +345,7 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._postal_code = None self._city = None self._region = None + self._state_abbr = None self._country = None self._county = None self._formatted_address = None @@ -401,6 +403,7 @@ def extra_state_attributes(self): ATTR_POSTAL_TOWN: self._postal_town, ATTR_POSTAL_CODE: self._postal_code, ATTR_REGION: self._region, + ATTR_STATE_ABBR: self._state_abbr ATTR_COUNTRY: self._country, ATTR_COUNTY: self._county, ATTR_FORMATTED_ADDRESS: self._formatted_address, @@ -578,6 +581,7 @@ def do_update(self, reason): city = '-' postal_town = '-' region = '-' + state_abbr = '-' county = '-' country = '-' postal_code = '' @@ -621,6 +625,8 @@ def do_update(self, reason): postal_town = osm_decoded["address"]["suburb"] if "state" in osm_decoded["address"]: region = osm_decoded["address"]["state"] + if "ISO3166-2-lvl4" in osm_decoded["address"]: + state_abbr = osm_decoded["address"]["ISO3166-2-lvl4"].split("-")[1].upper() if "county" in osm_decoded["address"]: county = osm_decoded["address"]["county"] if "country" in osm_decoded["address"]: @@ -640,6 +646,7 @@ def do_update(self, reason): self._city = city self._postal_town = postal_town self._region = region + self._state_abbr = state_abbr self._county = county self._country = country self._postal_code = postal_code @@ -758,6 +765,7 @@ def _reset_attributes(self): self._postal_town = None self._postal_code = None self._region = None + self._state_abbr = None self._country = None self._county = None self._formatted_address = None From bdf33981e535e10ff855dced96801eaafefc7ab7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 14 Jul 2022 21:05:42 -0400 Subject: [PATCH 004/329] Limit state to 255 characters Truncate the state to 255-14 characters. The 14 is for the " (since xx:yy)" added to the end of the state. --- custom_components/places/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 152117c4..c649f0d3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -730,6 +730,7 @@ def do_update(self, reason): if previous_state != new_state: _LOGGER.info( "(" + self._name + ") New state built using options: " + self._options) _LOGGER.debug( "(" + self._name + ") Building EventData for (" + new_state +")") + new_state = new_state[:(255-14)] self._state = new_state + " (since " + current_time + ")" event_data = {} event_data['entity'] = self._name From 0ffe628550e441a522b385fce5201b6627a8e71a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 16 Jul 2022 21:40:04 -0400 Subject: [PATCH 005/329] Missed a comma --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a700b40e..4e4e79f7 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -403,7 +403,7 @@ def extra_state_attributes(self): ATTR_POSTAL_TOWN: self._postal_town, ATTR_POSTAL_CODE: self._postal_code, ATTR_REGION: self._region, - ATTR_STATE_ABBR: self._state_abbr + ATTR_STATE_ABBR: self._state_abbr, ATTR_COUNTRY: self._country, ATTR_COUNTY: self._county, ATTR_FORMATTED_ADDRESS: self._formatted_address, From ed21dbf633c9499d75834405b12bd40c3535f362 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 16 Jul 2022 22:49:08 -0400 Subject: [PATCH 006/329] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2ccbe521..6cfe00cc 100644 --- a/README.md +++ b/README.md @@ -187,10 +187,10 @@ If you want to contribute to this please read the [Contribution guidelines](CONT *** -[places]: /~https://github.com/custom-components/places +[places]: /~https://github.com/Snuffy2/places [commits-shield]: https://img.shields.io/github/commit-activity/y/custom-components/places.svg?style=for-the-badge -[commits]: /~https://github.com/custom-components/places/commits/master -[hacs]: /~https://github.com/custom-components/hacs +[commits]: /~https://github.com/Snuffy2/places/commits/newdev +[hacs]: /~https://github.com/Snuffy2/places/hacs [hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge [discord]: https://discord.gg/Qa5fW2R [discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge @@ -199,4 +199,4 @@ If you want to contribute to this please read the [Contribution guidelines](CONT [license-shield]: https://img.shields.io/github/license/custom-components/places.svg?style=for-the-badge [maintenance-shield]: https://img.shields.io/badge/maintainer-Ian%20Richardson%20%40iantrich-blue.svg?style=for-the-badge [releases-shield]: https://img.shields.io/github/release/custom-components/places.svg?style=for-the-badge -[releases]: /~https://github.com/custom-components/places/releases +[releases]: /~https://github.com/Snuffy2/places/releases From caa64e5cdd58626bc7f71a18bf5e488e1e2d2d99 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 16 Jul 2022 22:56:05 -0400 Subject: [PATCH 007/329] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6cfe00cc..1012b016 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ [![hacs][hacsbadge]][hacs] -[![Discord][discord-shield]][discord] -[![Community Forum][forum-shield]][forum] + + _Component to integrate with OpenStreetMap Reverse Geocode (PLACE)_ From a6016c4790ffe32753e3717a3a7bd9d65af520e8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 16 Jul 2022 23:12:08 -0400 Subject: [PATCH 008/329] Stop making the Home Zone lowercase --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 152117c4..96a4b952 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -327,7 +327,7 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._api_key = api_key self._options = options.lower() self._devicetracker_id = devicetracker_id.lower() - self._home_zone = home_zone.lower() + self._home_zone = home_zone self._map_provider = map_provider.lower() self._map_zoom = map_zoom.lower() self._language = language.lower() From 6099bb415d8d0eb6f773b1e219e8d1fab1971c20 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 17 Jul 2022 22:11:12 -0400 Subject: [PATCH 009/329] Revert "Stop making the Home Zone lowercase" This reverts commit a6016c4790ffe32753e3717a3a7bd9d65af520e8. --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8c2811a8..8a563417 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -328,7 +328,7 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._api_key = api_key self._options = options.lower() self._devicetracker_id = devicetracker_id.lower() - self._home_zone = home_zone + self._home_zone = home_zone.lower() self._map_provider = map_provider.lower() self._map_zoom = map_zoom.lower() self._language = language.lower() From 3d926615be7b981186ffeb58a3da4119a4a0d5f9 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 7 Aug 2022 21:01:23 -0400 Subject: [PATCH 010/329] Update sensor.py --- custom_components/places/sensor.py | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8a563417..cffaae4d 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -278,6 +278,7 @@ ATTR_LOCATION_PREVIOUS = 'previous_location' ATTR_DIRECTION_OF_TRAVEL = 'direction_of_travel' ATTR_MAP_LINK = 'map_link' +ATTR_MY_FORMATTED_PLACE = 'my_formatted_place' DEFAULT_NAME = 'places' DEFAULT_OPTION = 'zone, place' @@ -368,6 +369,7 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._updateskipped = 0 self._direction = 'stationary' self._map_link = None + self._my_formatted_place = None #'https://www.google.com/maps/@' + home_latitude + "," + home_longitude + ',19z' # Check if devicetracker_id was specified correctly @@ -428,7 +430,8 @@ def extra_state_attributes(self): ATTR_HOME_LONGITUDE: self._home_longitude, ATTR_DIRECTION_OF_TRAVEL: self._direction, ATTR_MAP_LINK: self._map_link, - ATTR_OPTIONS: self._options + ATTR_OPTIONS: self._options, + ATTR_MY_FORMATTED_PLACE: self._my_formatted_place } @@ -587,6 +590,7 @@ def do_update(self, reason): postal_code = '' formatted_address = '' target_option = '' + my_formatted_place = '' if "place" in self._options: place_type = osm_decoded["type"] @@ -671,6 +675,38 @@ def do_update(self, reason): if city == '-': city = county +# My Formatted Place + my_formatted_place_array = [] + if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home" + if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ) + my_formatted_place_array.append('Driving') + if self._place_name == '-' + if self._place_category == 'highway' and self._street == 'Unnamed Road' + my_formatted_place_array.append(self._place_type|capitalize|replace("Proposed","")|replace("Construction","")|replace("-","")|trim+' '+self._place_category|capitalize|trim) + elif self._place_type == 'unclassified' or self._place_type == '-' + if self._place_category != '-' + my_formatted_place_array.append(self._place_category|capitalize|trim) + else + my_formatted_place_array.append(self._place_type|capitalize|trim) + if self._street != 'Unnamed Road' + my_formatted_place_array.append(self._street_number|replace("-","")|trim+' '+self._street|replace("-","")|trim) + elif self._place_neighbourhood != '-' + my_formatted_place_array.append(self._place_neighbourhood|trim+' Neighborhood') + else + my_formatted_place_array.append(self._place_name|trim) + if self._city != '-' + my_formatted_place_array.append(self._city|replace(" Township","")|trim) + elif self._county != '-' + my_formatted_place_array.append(self._county|trim) + if self._region != '-' + my_formatted_place_array.append(self._state_abbr) + else + my_formatted_place_array.append(self._devicetracker_zone|trim) + my_formatted_place = (', '.join( item for item in my_formatted_place_array))|replace('\n',' ')|regex_replace('\s{2,}',' ')|trim + self._my_formatted_place = my_formatted_place + +# End My Formatted Place + # Options: "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" _LOGGER.debug( "(" + self._name + ") Building State from Display Options: " + self._options) From 83a19fde730f0a757ace52240add339624506a48 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 7 Aug 2022 21:17:28 -0400 Subject: [PATCH 011/329] Update sensor.py --- custom_components/places/sensor.py | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index cffaae4d..e41060e2 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -677,32 +677,32 @@ def do_update(self, reason): # My Formatted Place my_formatted_place_array = [] - if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home" - if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ) + if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home": + if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): my_formatted_place_array.append('Driving') - if self._place_name == '-' - if self._place_category == 'highway' and self._street == 'Unnamed Road' - my_formatted_place_array.append(self._place_type|capitalize|replace("Proposed","")|replace("Construction","")|replace("-","")|trim+' '+self._place_category|capitalize|trim) - elif self._place_type == 'unclassified' or self._place_type == '-' - if self._place_category != '-' - my_formatted_place_array.append(self._place_category|capitalize|trim) - else - my_formatted_place_array.append(self._place_type|capitalize|trim) - if self._street != 'Unnamed Road' - my_formatted_place_array.append(self._street_number|replace("-","")|trim+' '+self._street|replace("-","")|trim) - elif self._place_neighbourhood != '-' - my_formatted_place_array.append(self._place_neighbourhood|trim+' Neighborhood') - else - my_formatted_place_array.append(self._place_name|trim) - if self._city != '-' - my_formatted_place_array.append(self._city|replace(" Township","")|trim) - elif self._county != '-' - my_formatted_place_array.append(self._county|trim) - if self._region != '-' + if self._place_name == '-': + if self._place_category == 'highway' and self._street == 'Unnamed Road': + my_formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) + elif self._place_type == 'unclassified' or self._place_type == '-': + if self._place_category != '-': + my_formatted_place_array.append(self._place_category.title().strip()) + else: + my_formatted_place_array.append(self._place_type.title().strip()) + if self._street != 'Unnamed Road': + my_formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) + elif self._place_neighbourhood != '-': + my_formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') + else: + my_formatted_place_array.append(self._place_name.strip()) + if self._city != '-': + my_formatted_place_array.append(self._city.replace(" Township","").strip()) + elif self._county != '-': + my_formatted_place_array.append(self._county.strip()) + if self._region != '-': my_formatted_place_array.append(self._state_abbr) - else - my_formatted_place_array.append(self._devicetracker_zone|trim) - my_formatted_place = (', '.join( item for item in my_formatted_place_array))|replace('\n',' ')|regex_replace('\s{2,}',' ')|trim + else: + my_formatted_place_array.append(self._devicetracker_zone.strip()) + my_formatted_place = (', '.join( item for item in my_formatted_place_array)).replace('\n',' ').replace(' ',' ').strip() self._my_formatted_place = my_formatted_place # End My Formatted Place From db7bc2c7e19436cf27eb41d4c7f6280ecc065d8a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 7 Aug 2022 21:24:15 -0400 Subject: [PATCH 012/329] Update sensor.py --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e41060e2..e16cef8a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -702,8 +702,8 @@ def do_update(self, reason): my_formatted_place_array.append(self._state_abbr) else: my_formatted_place_array.append(self._devicetracker_zone.strip()) - my_formatted_place = (', '.join( item for item in my_formatted_place_array)).replace('\n',' ').replace(' ',' ').strip() - self._my_formatted_place = my_formatted_place + my_formatted_place = (', '.join( item for item in my_formatted_place_array)).replace('\n',' ').replace(' ',' ').strip() + self._my_formatted_place = my_formatted_place # End My Formatted Place From 39a56050c061a590f3f4d843ad2be5b4e267c5e1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 7 Aug 2022 22:24:24 -0400 Subject: [PATCH 013/329] Update sensor.py --- custom_components/places/sensor.py | 78 ++++++++++++++++++------------ 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e16cef8a..8016788b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -514,9 +514,17 @@ def do_update(self, reason): """Update if location has changed.""" devicetracker_zone = self.hass.states.get(self._devicetracker_id).state + _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (before update): " + devicetracker_zone ) + + devicetracker_zone_id = self.hass.states.get(self._devicetracker_id).attributes.get('zone') + devicetracker_zone_id = 'zone.'+devicetracker_zone_id + _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone ID (before update): " + devicetracker_zone_id ) + + devicetracker_zone_name = self.hass.states.get(devicetracker_zone_id).name + _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone Name (before update): " + devicetracker_zone_name ) + distance_traveled = distance(float(new_latitude), float(new_longitude), float(old_latitude), float(old_longitude)) - _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (before update): " + devicetracker_zone ) _LOGGER.info( "(" + self._name + ") Meters traveled since last update: " + str(round(distance_traveled)) ) proceed_with_update = True @@ -675,37 +683,6 @@ def do_update(self, reason): if city == '-': city = county -# My Formatted Place - my_formatted_place_array = [] - if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home": - if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): - my_formatted_place_array.append('Driving') - if self._place_name == '-': - if self._place_category == 'highway' and self._street == 'Unnamed Road': - my_formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) - elif self._place_type == 'unclassified' or self._place_type == '-': - if self._place_category != '-': - my_formatted_place_array.append(self._place_category.title().strip()) - else: - my_formatted_place_array.append(self._place_type.title().strip()) - if self._street != 'Unnamed Road': - my_formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) - elif self._place_neighbourhood != '-': - my_formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') - else: - my_formatted_place_array.append(self._place_name.strip()) - if self._city != '-': - my_formatted_place_array.append(self._city.replace(" Township","").strip()) - elif self._county != '-': - my_formatted_place_array.append(self._county.strip()) - if self._region != '-': - my_formatted_place_array.append(self._state_abbr) - else: - my_formatted_place_array.append(self._devicetracker_zone.strip()) - my_formatted_place = (', '.join( item for item in my_formatted_place_array)).replace('\n',' ').replace(' ',' ').strip() - self._my_formatted_place = my_formatted_place - -# End My Formatted Place # Options: "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" @@ -777,6 +754,43 @@ def do_update(self, reason): new_state = devicetracker_zone _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker set to: " + new_state) + # My Formatted Place + my_formatted_place_array = [] + if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home": + if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): + my_formatted_place_array.append('Driving') + if self._place_name == '-': + if self._place_category == 'highway' and self._street == 'Unnamed Road': + my_formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) + elif self._place_type == 'unclassified' or self._place_type == '-': + if self._place_category != '-': + my_formatted_place_array.append(self._place_category.title().strip()) + else: + my_formatted_place_array.append(self._place_type.title().strip()) + if self._street != 'Unnamed Road': + my_formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) + elif self._place_neighbourhood != '-': + my_formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') + else: + my_formatted_place_array.append(self._place_name.strip()) + if self._city != '-': + my_formatted_place_array.append(self._city.replace(" Township","").strip()) + elif self._county != '-': + my_formatted_place_array.append(self._county.strip()) + if self._region != '-': + my_formatted_place_array.append(self._state_abbr) + #elif self._devicetracker_zone == 'home': + #my_formatted_place_array.append(self._devicetracker_zone.title().strip()) + else: + #my_formatted_place_array.append(self._devicetracker_zone.strip()) + my_formatted_place_array.append(devicetracker_zone_name.strip()) + my_formatted_place = ', '.join( item for item in my_formatted_place_array) + my_formatted_place = my_formatted_place.replace('\n',' ').replace(' ',' ').strip() + self._my_formatted_place = my_formatted_place + + # End My Formatted Place + + current_time = "%02d:%02d" % (now.hour, now.minute) if previous_state != new_state: From b57477ce0684ed59ef416d833e190658f22f6365 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 7 Aug 2022 22:32:17 -0400 Subject: [PATCH 014/329] Update sensor.py --- custom_components/places/sensor.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8a563417..5acb52e1 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -263,6 +263,7 @@ ATTR_PLACE_NEIGHBOURHOOD = 'neighbourhood' ATTR_DEVICETRACKER_ID = 'devicetracker_entityid' ATTR_DEVICETRACKER_ZONE = 'devicetracker_zone' +ATTR_DEVICETRACKER_ZONE_NAME = 'devicetracker_zone_name' ATTR_PICTURE = 'entity_picture' ATTR_LATITUDE_OLD = 'previous_latitude' ATTR_LONGITUDE_OLD = 'previous_longitude' @@ -360,6 +361,7 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._latitude = home_latitude self._longitude = home_longitude self._devicetracker_zone = 'Home' + self._devicetracker_zone_name = 'Home' self._mtime = str(datetime.now()) self._distance_km = 0 self._distance_m = 0 @@ -417,6 +419,7 @@ def extra_state_attributes(self): ATTR_LONGITUDE: self._longitude, ATTR_DEVICETRACKER_ID: self._devicetracker_id, ATTR_DEVICETRACKER_ZONE: self._devicetracker_zone, + ATTR_DEVICETRACKER_ZONE_NAME: self._devicetracker_zone_name, ATTR_HOME_ZONE: self._home_zone, ATTR_PICTURE: self._entity_picture, ATTR_DISTANCE_KM: self._distance_km, @@ -511,9 +514,17 @@ def do_update(self, reason): """Update if location has changed.""" devicetracker_zone = self.hass.states.get(self._devicetracker_id).state + _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (before update): " + devicetracker_zone ) + + devicetracker_zone_id = self.hass.states.get(self._devicetracker_id).attributes.get('zone') + devicetracker_zone_id = 'zone.'+devicetracker_zone_id + _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone ID (before update): " + devicetracker_zone_id ) + + devicetracker_zone_name = self.hass.states.get(devicetracker_zone_id).name + _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone Name (before update): " + devicetracker_zone_name ) + distance_traveled = distance(float(new_latitude), float(new_longitude), float(old_latitude), float(old_longitude)) - _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (before update): " + devicetracker_zone ) _LOGGER.info( "(" + self._name + ") Meters traveled since last update: " + str(round(distance_traveled)) ) proceed_with_update = True @@ -547,6 +558,7 @@ def do_update(self, reason): self._location_current = current_location self._location_previous = previous_location self._devicetracker_zone = devicetracker_zone + self._devicetracker_zone_name = devicetracker_zone_name self._distance_km = distance_from_home self._distance_m = distance_m self._direction = direction @@ -756,6 +768,7 @@ def do_update(self, reason): event_data['distance_from_home'] = distance_from_home event_data['direction'] = direction event_data['devicetracker_zone'] = devicetracker_zone + event_data['devicetracker_zone_name'] = devicetracker_zone_name event_data['latitude'] = self._latitude event_data['longitude'] = self._longitude event_data['previous_latitude'] = self._latitude_old From 228fa8732a50fa5e2a51656b5322f31c494bd337 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 20:51:23 -0400 Subject: [PATCH 015/329] Update sensor.py --- custom_components/places/sensor.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e227d297..ac8bb61c 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -523,7 +523,11 @@ def do_update(self, reason): devicetracker_zone_id = 'zone.'+devicetracker_zone_id _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone ID (before update): " + devicetracker_zone_id ) - devicetracker_zone_name = self.hass.states.get(devicetracker_zone_id).name + devicetracker_zone_name_state = self.hass.states.get(devicetracker_zone_id) + if devicetracker_zone_name_state: + devicetracker_zone_name = self.hass.states.get(devicetracker_zone_id).name + else: + devicetracker_zone_name = devicetracker_zone _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone Name (before update): " + devicetracker_zone_name ) distance_traveled = distance(float(new_latitude), float(new_longitude), float(old_latitude), float(old_longitude)) From 515449d0db0b2ac28e8c522e0d3779aec16b822b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 21:02:34 -0400 Subject: [PATCH 016/329] Update sensor.py --- custom_components/places/sensor.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 152117c4..fc6dedeb 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -262,6 +262,7 @@ ATTR_PLACE_NEIGHBOURHOOD = 'neighbourhood' ATTR_DEVICETRACKER_ID = 'devicetracker_entityid' ATTR_DEVICETRACKER_ZONE = 'devicetracker_zone' +ATTR_DEVICETRACKER_ZONE_NAME = 'devicetracker_zone_name' ATTR_PICTURE = 'entity_picture' ATTR_LATITUDE_OLD = 'previous_latitude' ATTR_LONGITUDE_OLD = 'previous_longitude' @@ -358,6 +359,7 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._latitude = home_latitude self._longitude = home_longitude self._devicetracker_zone = 'Home' + self._devicetracker_zone_name = 'Home' self._mtime = str(datetime.now()) self._distance_km = 0 self._distance_m = 0 @@ -414,6 +416,7 @@ def extra_state_attributes(self): ATTR_LONGITUDE: self._longitude, ATTR_DEVICETRACKER_ID: self._devicetracker_id, ATTR_DEVICETRACKER_ZONE: self._devicetracker_zone, + ATTR_DEVICETRACKER_ZONE_NAME: self._devicetracker_zone_name, ATTR_HOME_ZONE: self._home_zone, ATTR_PICTURE: self._entity_picture, ATTR_DISTANCE_KM: self._distance_km, @@ -507,10 +510,23 @@ def do_update(self, reason): """Update if location has changed.""" + devicetracker_zone = self.hass.states.get(self._devicetracker_id).state + _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (before update): " + devicetracker_zone ) + + devicetracker_zone_id = self.hass.states.get(self._devicetracker_id).attributes.get('zone') + devicetracker_zone_id = 'zone.'+devicetracker_zone_id + _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone ID (before update): " + devicetracker_zone_id ) + + devicetracker_zone_name_state = self.hass.states.get(devicetracker_zone_id) + if devicetracker_zone_name_state: + devicetracker_zone_name = self.hass.states.get(devicetracker_zone_id).name + else: + devicetracker_zone_name = devicetracker_zone + _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone Name (before update): " + devicetracker_zone_name ) + distance_traveled = distance(float(new_latitude), float(new_longitude), float(old_latitude), float(old_longitude)) - _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (before update): " + devicetracker_zone ) _LOGGER.info( "(" + self._name + ") Meters traveled since last update: " + str(round(distance_traveled)) ) proceed_with_update = True @@ -544,6 +560,7 @@ def do_update(self, reason): self._location_current = current_location self._location_previous = previous_location self._devicetracker_zone = devicetracker_zone + self._devicetracker_zone_name = devicetracker_zone_name self._distance_km = distance_from_home self._distance_m = distance_m self._direction = direction @@ -739,6 +756,7 @@ def do_update(self, reason): event_data['distance_from_home'] = distance_from_home event_data['direction'] = direction event_data['devicetracker_zone'] = devicetracker_zone + event_data['devicetracker_zone_name'] = devicetracker_zone_name event_data['latitude'] = self._latitude event_data['longitude'] = self._longitude event_data['previous_latitude'] = self._latitude_old From 40c3b167c96070b93e29cee809144a0532611ab9 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 21:43:01 -0400 Subject: [PATCH 017/329] Make Time an Option --- custom_components/places/sensor.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e492fe35..12bf7d2d 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -805,8 +805,11 @@ def do_update(self, reason): if previous_state != new_state: _LOGGER.info( "(" + self._name + ") New state built using options: " + self._options) _LOGGER.debug( "(" + self._name + ") Building EventData for (" + new_state +")") - new_state = new_state[:(255-14)] - self._state = new_state + " (since " + current_time + ")" + if "time" in display_options: + new_state = new_state[:(255-14)] + self._state = new_state + " (since " + current_time + ")" + else: + self._state = new_state event_data = {} event_data['entity'] = self._name event_data['place_name'] = place_name From 90d930e93e2a769512db5337e8885f515aae9f73 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 21:48:51 -0400 Subject: [PATCH 018/329] Fix tab indent --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 12bf7d2d..df1537ab 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -809,7 +809,7 @@ def do_update(self, reason): new_state = new_state[:(255-14)] self._state = new_state + " (since " + current_time + ")" else: - self._state = new_state + self._state = new_state event_data = {} event_data['entity'] = self._name event_data['place_name'] = place_name From 6f5a5603278dbeb244f30a577b207f84a9690fe5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 22:06:24 -0400 Subject: [PATCH 019/329] Remove time in state altogether Uncomment current_time --- custom_components/places/sensor.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index df1537ab..128bedea 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -805,11 +805,10 @@ def do_update(self, reason): if previous_state != new_state: _LOGGER.info( "(" + self._name + ") New state built using options: " + self._options) _LOGGER.debug( "(" + self._name + ") Building EventData for (" + new_state +")") - if "time" in display_options: - new_state = new_state[:(255-14)] - self._state = new_state + " (since " + current_time + ")" - else: - self._state = new_state + #new_state = new_state[:(255-14)] + #self._state = new_state + " (since " + current_time + ")" + new_state = new_state[:255] + self._state = new_state event_data = {} event_data['entity'] = self._name event_data['place_name'] = place_name From a6ac193ab15a27eb481feddf8affe5f8de2bd303 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 22:18:14 -0400 Subject: [PATCH 020/329] Rename My Formatted Place to Formatted Place --- custom_components/places/sensor.py | 46 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 128bedea..6c8ac6f1 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -279,7 +279,7 @@ ATTR_LOCATION_PREVIOUS = 'previous_location' ATTR_DIRECTION_OF_TRAVEL = 'direction_of_travel' ATTR_MAP_LINK = 'map_link' -ATTR_MY_FORMATTED_PLACE = 'my_formatted_place' +ATTR_FORMATTED_PLACE = 'formatted_place' DEFAULT_NAME = 'places' DEFAULT_OPTION = 'zone, place' @@ -371,7 +371,7 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._updateskipped = 0 self._direction = 'stationary' self._map_link = None - self._my_formatted_place = None + self._formatted_place = None #'https://www.google.com/maps/@' + home_latitude + "," + home_longitude + ',19z' # Check if devicetracker_id was specified correctly @@ -434,7 +434,7 @@ def extra_state_attributes(self): ATTR_DIRECTION_OF_TRAVEL: self._direction, ATTR_MAP_LINK: self._map_link, ATTR_OPTIONS: self._options, - ATTR_MY_FORMATTED_PLACE: self._my_formatted_place + ATTR_FORMATTED_PLACE: self._formatted_place } @@ -607,7 +607,7 @@ def do_update(self, reason): postal_code = '' formatted_address = '' target_option = '' - my_formatted_place = '' + formatted_place = '' if "place" in self._options: place_type = osm_decoded["type"] @@ -763,41 +763,41 @@ def do_update(self, reason): new_state = devicetracker_zone _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker set to: " + new_state) - # My Formatted Place - my_formatted_place_array = [] + # Formatted Place + formatted_place_array = [] if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home": if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): - my_formatted_place_array.append('Driving') + formatted_place_array.append('Driving') if self._place_name == '-': if self._place_category == 'highway' and self._street == 'Unnamed Road': - my_formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) + formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) elif self._place_type == 'unclassified' or self._place_type == '-': if self._place_category != '-': - my_formatted_place_array.append(self._place_category.title().strip()) + formatted_place_array.append(self._place_category.title().strip()) else: - my_formatted_place_array.append(self._place_type.title().strip()) + formatted_place_array.append(self._place_type.title().strip()) if self._street != 'Unnamed Road': - my_formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) + formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) elif self._place_neighbourhood != '-': - my_formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') + formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') else: - my_formatted_place_array.append(self._place_name.strip()) + formatted_place_array.append(self._place_name.strip()) if self._city != '-': - my_formatted_place_array.append(self._city.replace(" Township","").strip()) + formatted_place_array.append(self._city.replace(" Township","").strip()) elif self._county != '-': - my_formatted_place_array.append(self._county.strip()) + formatted_place_array.append(self._county.strip()) if self._region != '-': - my_formatted_place_array.append(self._state_abbr) + formatted_place_array.append(self._state_abbr) #elif self._devicetracker_zone == 'home': - #my_formatted_place_array.append(self._devicetracker_zone.title().strip()) + #formatted_place_array.append(self._devicetracker_zone.title().strip()) else: - #my_formatted_place_array.append(self._devicetracker_zone.strip()) - my_formatted_place_array.append(devicetracker_zone_name.strip()) - my_formatted_place = ', '.join( item for item in my_formatted_place_array) - my_formatted_place = my_formatted_place.replace('\n',' ').replace(' ',' ').strip() - self._my_formatted_place = my_formatted_place + #formatted_place_array.append(self._devicetracker_zone.strip()) + formatted_place_array.append(devicetracker_zone_name.strip()) + formatted_place = ', '.join( item for item in formatted_place_array) + formatted_place = formatted_place.replace('\n',' ').replace(' ',' ').strip() + self._formatted_place = formatted_place - # End My Formatted Place + # End Formatted Place current_time = "%02d:%02d" % (now.hour, now.minute) From 5448513ef8251da941a08a19cde60337c18586a9 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 22:20:26 -0400 Subject: [PATCH 021/329] Move Formatted Place code to the proper place in the file --- custom_components/places/sensor.py | 72 ++++++++++++++---------------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6c8ac6f1..a27f8e2c 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -682,7 +682,40 @@ def do_update(self, reason): self._postal_code = postal_code self._formatted_address = formatted_address self._mtime = str(datetime.now()) - + + # Formatted Place + formatted_place_array = [] + if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home": + if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): + formatted_place_array.append('Driving') + if self._place_name == '-': + if self._place_category == 'highway' and self._street == 'Unnamed Road': + formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) + elif self._place_type == 'unclassified' or self._place_type == '-': + if self._place_category != '-': + formatted_place_array.append(self._place_category.title().strip()) + else: + formatted_place_array.append(self._place_type.title().strip()) + if self._street != 'Unnamed Road': + formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) + elif self._place_neighbourhood != '-': + formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') + else: + formatted_place_array.append(self._place_name.strip()) + if self._city != '-': + formatted_place_array.append(self._city.replace(" Township","").strip()) + elif self._county != '-': + formatted_place_array.append(self._county.strip()) + if self._region != '-': + formatted_place_array.append(self._state_abbr) + else: + formatted_place_array.append(devicetracker_zone_name.strip()) + formatted_place = ', '.join( item for item in formatted_place_array) + formatted_place = formatted_place.replace('\n',' ').replace(' ',' ').strip() + self._formatted_place = formatted_place + + # End Formatted Place + if 'error_message' in osm_decoded: new_state = osm_decoded['error_message'] _LOGGER.info( "(" + self._name + ") An error occurred contacting the web service") @@ -692,7 +725,6 @@ def do_update(self, reason): if city == '-': city = county - # Options: "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" _LOGGER.debug( "(" + self._name + ") Building State from Display Options: " + self._options) @@ -763,42 +795,6 @@ def do_update(self, reason): new_state = devicetracker_zone _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker set to: " + new_state) - # Formatted Place - formatted_place_array = [] - if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home": - if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): - formatted_place_array.append('Driving') - if self._place_name == '-': - if self._place_category == 'highway' and self._street == 'Unnamed Road': - formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) - elif self._place_type == 'unclassified' or self._place_type == '-': - if self._place_category != '-': - formatted_place_array.append(self._place_category.title().strip()) - else: - formatted_place_array.append(self._place_type.title().strip()) - if self._street != 'Unnamed Road': - formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) - elif self._place_neighbourhood != '-': - formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') - else: - formatted_place_array.append(self._place_name.strip()) - if self._city != '-': - formatted_place_array.append(self._city.replace(" Township","").strip()) - elif self._county != '-': - formatted_place_array.append(self._county.strip()) - if self._region != '-': - formatted_place_array.append(self._state_abbr) - #elif self._devicetracker_zone == 'home': - #formatted_place_array.append(self._devicetracker_zone.title().strip()) - else: - #formatted_place_array.append(self._devicetracker_zone.strip()) - formatted_place_array.append(devicetracker_zone_name.strip()) - formatted_place = ', '.join( item for item in formatted_place_array) - formatted_place = formatted_place.replace('\n',' ').replace(' ',' ').strip() - self._formatted_place = formatted_place - - # End Formatted Place - current_time = "%02d:%02d" % (now.hour, now.minute) From 0775183c653031c8d768a7121ee98cd57a305c9c Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 22:23:21 -0400 Subject: [PATCH 022/329] Further cleanup of city code --- custom_components/places/sensor.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a27f8e2c..a501b498 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -648,6 +648,8 @@ def do_update(self, reason): city = osm_decoded["address"]["township"] elif "municipality" in osm_decoded["address"]: city = osm_decoded["address"]["municipality"] + elif "city_district" in osm_decoded["address"]: + city = osm_decoded["address"]["city_district"] if "city_district" in osm_decoded["address"]: postal_town = osm_decoded["address"]["city_district"] @@ -720,10 +722,6 @@ def do_update(self, reason): new_state = osm_decoded['error_message'] _LOGGER.info( "(" + self._name + ") An error occurred contacting the web service") elif self._devicetracker_zone == "not_home": - if city == '-': - city = postal_town - if city == '-': - city = county # Options: "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" From 833ea3fc2edee06592e6b37e73df41b244c2b59d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 22:34:16 -0400 Subject: [PATCH 023/329] Add Formatted Place as an Exclusive Option --- custom_components/places/sensor.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a501b498..3f2131e4 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -718,19 +718,21 @@ def do_update(self, reason): # End Formatted Place + display_options = [] + options_array = self._options.split(',') + for option in options_array: + display_options.append(option.strip()) + if 'error_message' in osm_decoded: new_state = osm_decoded['error_message'] _LOGGER.info( "(" + self._name + ") An error occurred contacting the web service") + elif "formatted_place" in display_options: + new_state = self._formatted_place elif self._devicetracker_zone == "not_home": # Options: "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" _LOGGER.debug( "(" + self._name + ") Building State from Display Options: " + self._options) - - display_options = [] - options_array = self._options.split(',') - for option in options_array: - display_options.append(option.strip()) user_display = [] From f7115b99c29deff3d08d8fce873e925eaf390365 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 22:55:47 -0400 Subject: [PATCH 024/329] Update README.md Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1012b016..749db3f9 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Key | Type | Required | Description | Default | `map_provider` | `string` | `False` | `google` or `apple` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` `language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s). | *Refer to Notes -`options` | `string` | `False` | Display options: `zone, place, place_name, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home` | `zone, place` +`options` | `string` | `False` | Display options: `formaated_place (exclusive option), zone or zone_name, place, place_name, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home` | `zone, place` Sample attributes that can be used in notifications, alerts, automations, etc: ```json From 722d86264288eaf24c18e21c9b14cde160865c5b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 8 Aug 2022 23:08:39 -0400 Subject: [PATCH 025/329] Add zone_name as option --- custom_components/places/sensor.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 3f2131e4..1e631040 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -730,15 +730,19 @@ def do_update(self, reason): new_state = self._formatted_place elif self._devicetracker_zone == "not_home": - # Options: "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" + # Options: "formatted_place, zone, zone_name, place, street_number, street, city, county, state, postal_code, country, formatted_address" _LOGGER.debug( "(" + self._name + ") Building State from Display Options: " + self._options) user_display = [] - if "zone" in display_options and ("do_not_show_not_home" not in display_options and self._devicetracker_zone != "not_home"): + if "zone_name" in display_options and "do_not_show_not_home" not in display_options: zone = self._devicetracker_zone - user_display.append(zone) + user_display.append(self._devicetracker_zone_name) + elif "zone" in display_options and "do_not_show_not_home" not in display_options: + zone = self._devicetracker_zone + user_display.append(self._devicetracker_zone) + if "place_name" in display_options: if place_name != "-": user_display.append(place_name) @@ -782,7 +786,6 @@ def do_update(self, reason): target_option = "place_neighbourhood" if option in locals(): user_display.append(target_option) - if not user_display: user_display = self._devicetracker_zone @@ -791,11 +794,13 @@ def do_update(self, reason): new_state = ', '.join( item for item in user_display ) _LOGGER.debug( "(" + self._name + ") New State built from Display Options will be: " + new_state ) + elif "zone_name" in display_options: + new_state = devicetracker_zone_name + _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker set to: " + new_state) else: new_state = devicetracker_zone _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker set to: " + new_state) - current_time = "%02d:%02d" % (now.hour, now.minute) if previous_state != new_state: From 4b4a37dafe3afcec5404b875c06d63174c209a7e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 9 Aug 2022 21:15:42 -0400 Subject: [PATCH 026/329] Factor in Stationary Zones --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 1e631040..82afa86b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -687,7 +687,7 @@ def do_update(self, reason): # Formatted Place formatted_place_array = [] - if self._devicetracker_zone == "stationary" or self._devicetracker_zone == "away" or self._devicetracker_zone == "not_home": + if "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home": if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): formatted_place_array.append('Driving') if self._place_name == '-': @@ -728,7 +728,7 @@ def do_update(self, reason): _LOGGER.info( "(" + self._name + ") An error occurred contacting the web service") elif "formatted_place" in display_options: new_state = self._formatted_place - elif self._devicetracker_zone == "not_home": + elif self._devicetracker_zone.lower() == "not_home" or "stationary" in self._devicetracker_zone.lower(): # Options: "formatted_place, zone, zone_name, place, street_number, street, city, county, state, postal_code, country, formatted_address" From 68cd993b668b2d42f995594e8efadaed97c41967 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 9 Aug 2022 21:33:32 -0400 Subject: [PATCH 027/329] Make Driving a Display Option Will work as regular option or with formatted_place. Not very accurate anyway. --- README.md | 3 ++- custom_components/places/sensor.py | 22 +++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 749db3f9..53b31784 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Key | Type | Required | Description | Default | `map_provider` | `string` | `False` | `google` or `apple` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` `language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s). | *Refer to Notes -`options` | `string` | `False` | Display options: `formaated_place (exclusive option), zone or zone_name, place, place_name, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home` | `zone, place` +`options` | `string` | `False` | Display options: `formatted_place (exclusive option), driving (can be used with formatted_place or other options), zone or zone_name, place, place_name, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home` | `zone, place` Sample attributes that can be used in notifications, alerts, automations, etc: ```json @@ -180,6 +180,7 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat ``` Original Author: [Jim Thompson](/~https://github.com/tenly2000) +Subsequent Author: [Ian Richardson](/~https://github.com/iantrich) ## Contributions are welcome! diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 82afa86b..c1f34e3a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -684,12 +684,20 @@ def do_update(self, reason): self._postal_code = postal_code self._formatted_address = formatted_address self._mtime = str(datetime.now()) + + isDriving = False + + display_options = [] + options_array = self._options.split(',') + for option in options_array: + display_options.append(option.strip()) # Formatted Place formatted_place_array = [] if "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home": - if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ): + if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ) and "driving" in display_options: formatted_place_array.append('Driving') + isDriving = True if self._place_name == '-': if self._place_category == 'highway' and self._street == 'Unnamed Road': formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) @@ -714,14 +722,7 @@ def do_update(self, reason): formatted_place_array.append(devicetracker_zone_name.strip()) formatted_place = ', '.join( item for item in formatted_place_array) formatted_place = formatted_place.replace('\n',' ').replace(' ',' ').strip() - self._formatted_place = formatted_place - - # End Formatted Place - - display_options = [] - options_array = self._options.split(',') - for option in options_array: - display_options.append(option.strip()) + self._formatted_place = formatted_place if 'error_message' in osm_decoded: new_state = osm_decoded['error_message'] @@ -735,6 +736,9 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name + ") Building State from Display Options: " + self._options) user_display = [] + + if "driving" in display_options and isDriving: + user_display.append("Driving") if "zone_name" in display_options and "do_not_show_not_home" not in display_options: zone = self._devicetracker_zone From 279b78eb5ce6cb87c2f38403781694c45c7f7655 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 9 Aug 2022 22:18:02 -0400 Subject: [PATCH 028/329] Update README.md Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 53b31784..7493f652 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![GitHub Release][releases-shield]][releases] [![GitHub Activity][commits-shield]][commits] -[![License][license-shield]](LICENSE.md) +[![License][license-shield]](LICENSE) [![hacs][hacsbadge]][hacs] @@ -179,8 +179,8 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat custom_components.sensor.places: debug ``` -Original Author: [Jim Thompson](/~https://github.com/tenly2000) -Subsequent Author: [Ian Richardson](/~https://github.com/iantrich) +* Original Author: [Jim Thompson](/~https://github.com/tenly2000) +* Subsequent Author: [Ian Richardson](/~https://github.com/iantrich) ## Contributions are welcome! @@ -189,15 +189,15 @@ If you want to contribute to this please read the [Contribution guidelines](CONT *** [places]: /~https://github.com/Snuffy2/places -[commits-shield]: https://img.shields.io/github/commit-activity/y/custom-components/places.svg?style=for-the-badge +[commits-shield]: https://img.shields.io/github/commit-activity/y/Snuffy2/places?style=for-the-badge [commits]: /~https://github.com/Snuffy2/places/commits/newdev -[hacs]: /~https://github.com/Snuffy2/places/hacs +[hacs]: /~https://github.com/Snuffy2/hacs [hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge [discord]: https://discord.gg/Qa5fW2R [discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge [forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge [forum]: https://community.home-assistant.io/t/reverse-geocode-sensor-places-using-openstreetmap-custom-component -[license-shield]: https://img.shields.io/github/license/custom-components/places.svg?style=for-the-badge -[maintenance-shield]: https://img.shields.io/badge/maintainer-Ian%20Richardson%20%40iantrich-blue.svg?style=for-the-badge -[releases-shield]: https://img.shields.io/github/release/custom-components/places.svg?style=for-the-badge +[license-shield]: https://img.shields.io/github/license/Snuffy2/places.svg?style=for-the-badge +[releases-shield]: https://img.shields.io/github/v/release/Snuffy2/places?style=for-the-badge [releases]: /~https://github.com/Snuffy2/places/releases + From 212e024d698135b4f4dda288733acd5d13a7ddab Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 9 Aug 2022 23:17:16 -0400 Subject: [PATCH 029/329] Code Formatting Cleanup with Black --- custom_components/places/sensor.py | 769 +++++++++++++++++++---------- 1 file changed, 514 insertions(+), 255 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index c1f34e3a..5ac6610e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -232,79 +232,81 @@ from homeassistant.util import Throttle from homeassistant.util.location import distance from homeassistant.helpers.entity import Entity -from homeassistant.const import ( - CONF_API_KEY, CONF_NAME, CONF_SCAN_INTERVAL) +from homeassistant.const import CONF_API_KEY, CONF_NAME, CONF_SCAN_INTERVAL _LOGGER = logging.getLogger(__name__) -DEPENDENCIES = ['zone', 'device_tracker'] - -CONF_DEVICETRACKER_ID = 'devicetracker_id' -CONF_HOME_ZONE = 'home_zone' -CONF_OPTIONS = 'options' -CONF_MAP_PROVIDER = 'map_provider' -CONF_MAP_ZOOM = 'map_zoom' -CONF_LANGUAGE = 'language' - -ATTR_OPTIONS = 'options' -ATTR_STREET_NUMBER = 'street_number' -ATTR_STREET = 'street' -ATTR_CITY = 'city' -ATTR_POSTAL_TOWN = 'postal_town' -ATTR_POSTAL_CODE = 'postal_code' -ATTR_REGION = 'state_province' -ATTR_STATE_ABBR = 'state_abbr' -ATTR_COUNTRY = 'country' -ATTR_COUNTY = 'county' -ATTR_FORMATTED_ADDRESS = 'formatted_address' -ATTR_PLACE_TYPE = 'place_type' -ATTR_PLACE_NAME = 'place_name' -ATTR_PLACE_CATEGORY = 'place_category' -ATTR_PLACE_NEIGHBOURHOOD = 'neighbourhood' -ATTR_DEVICETRACKER_ID = 'devicetracker_entityid' -ATTR_DEVICETRACKER_ZONE = 'devicetracker_zone' -ATTR_DEVICETRACKER_ZONE_NAME = 'devicetracker_zone_name' -ATTR_PICTURE = 'entity_picture' -ATTR_LATITUDE_OLD = 'previous_latitude' -ATTR_LONGITUDE_OLD = 'previous_longitude' -ATTR_LATITUDE = 'current_latitude' -ATTR_LONGITUDE = 'current_longitude' -ATTR_MTIME = 'last_changed' -ATTR_DISTANCE_KM = 'distance_from_home_km' -ATTR_DISTANCE_M = 'distance_from_home_m' -ATTR_HOME_ZONE = 'home_zone' -ATTR_HOME_LATITUDE = 'home_latitude' -ATTR_HOME_LONGITUDE = 'home_longitude' -ATTR_LOCATION_CURRENT = 'current_location' -ATTR_LOCATION_PREVIOUS = 'previous_location' -ATTR_DIRECTION_OF_TRAVEL = 'direction_of_travel' -ATTR_MAP_LINK = 'map_link' -ATTR_FORMATTED_PLACE = 'formatted_place' - -DEFAULT_NAME = 'places' -DEFAULT_OPTION = 'zone, place' -DEFAULT_HOME_ZONE = 'zone.home' +DEPENDENCIES = ["zone", "device_tracker"] + +CONF_DEVICETRACKER_ID = "devicetracker_id" +CONF_HOME_ZONE = "home_zone" +CONF_OPTIONS = "options" +CONF_MAP_PROVIDER = "map_provider" +CONF_MAP_ZOOM = "map_zoom" +CONF_LANGUAGE = "language" + +ATTR_OPTIONS = "options" +ATTR_STREET_NUMBER = "street_number" +ATTR_STREET = "street" +ATTR_CITY = "city" +ATTR_POSTAL_TOWN = "postal_town" +ATTR_POSTAL_CODE = "postal_code" +ATTR_REGION = "state_province" +ATTR_STATE_ABBR = "state_abbr" +ATTR_COUNTRY = "country" +ATTR_COUNTY = "county" +ATTR_FORMATTED_ADDRESS = "formatted_address" +ATTR_PLACE_TYPE = "place_type" +ATTR_PLACE_NAME = "place_name" +ATTR_PLACE_CATEGORY = "place_category" +ATTR_PLACE_NEIGHBOURHOOD = "neighbourhood" +ATTR_DEVICETRACKER_ID = "devicetracker_entityid" +ATTR_DEVICETRACKER_ZONE = "devicetracker_zone" +ATTR_DEVICETRACKER_ZONE_NAME = "devicetracker_zone_name" +ATTR_PICTURE = "entity_picture" +ATTR_LATITUDE_OLD = "previous_latitude" +ATTR_LONGITUDE_OLD = "previous_longitude" +ATTR_LATITUDE = "current_latitude" +ATTR_LONGITUDE = "current_longitude" +ATTR_MTIME = "last_changed" +ATTR_DISTANCE_KM = "distance_from_home_km" +ATTR_DISTANCE_M = "distance_from_home_m" +ATTR_HOME_ZONE = "home_zone" +ATTR_HOME_LATITUDE = "home_latitude" +ATTR_HOME_LONGITUDE = "home_longitude" +ATTR_LOCATION_CURRENT = "current_location" +ATTR_LOCATION_PREVIOUS = "previous_location" +ATTR_DIRECTION_OF_TRAVEL = "direction_of_travel" +ATTR_MAP_LINK = "map_link" +ATTR_FORMATTED_PLACE = "formatted_place" + +DEFAULT_NAME = "places" +DEFAULT_OPTION = "zone, place" +DEFAULT_HOME_ZONE = "zone.home" DEFAULT_KEY = "no key" -DEFAULT_MAP_PROVIDER = 'apple' -DEFAULT_MAP_ZOOM = '18' -DEFAULT_LANGUAGE = 'default' +DEFAULT_MAP_PROVIDER = "apple" +DEFAULT_MAP_ZOOM = "18" +DEFAULT_LANGUAGE = "default" SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_DEVICETRACKER_ID): cv.string, - vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): cv.string, - vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): cv.string, - vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): cv.string, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, - vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.string, - vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, - vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, -}) +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( + { + vol.Required(CONF_DEVICETRACKER_ID): cv.string, + vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): cv.string, + vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): cv.string, + vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, + vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.string, + vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, + vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + } +) + +TRACKABLE_DOMAINS = ["device_tracker"] -TRACKABLE_DOMAINS = ['device_tracker'] def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the sensor platform.""" @@ -317,13 +319,38 @@ def setup_platform(hass, config, add_devices, discovery_info=None): map_zoom = config.get(CONF_MAP_ZOOM) language = config.get(CONF_LANGUAGE) - add_devices([Places(hass, devicetracker_id, name, api_key, options, home_zone, map_provider, map_zoom, language)]) + add_devices( + [ + Places( + hass, + devicetracker_id, + name, + api_key, + options, + home_zone, + map_provider, + map_zoom, + language, + ) + ] + ) class Places(Entity): """Representation of a Places Sensor.""" - def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, map_provider, map_zoom, language): + def __init__( + self, + hass, + devicetracker_id, + name, + api_key, + options, + home_zone, + map_provider, + map_zoom, + language, + ): """Initialize the sensor.""" self._hass = hass self._name = name @@ -337,9 +364,13 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._language.replace(" ", "") self._state = "Initializing... (since 99:99)" - home_latitude = str(hass.states.get(home_zone).attributes.get('latitude')) - home_longitude = str(hass.states.get(home_zone).attributes.get('longitude')) - self._entity_picture = hass.states.get(devicetracker_id).attributes.get('entity_picture') if hass.states.get(devicetracker_id) else None + home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) + home_longitude = str(hass.states.get(home_zone).attributes.get("longitude")) + self._entity_picture = ( + hass.states.get(devicetracker_id).attributes.get("entity_picture") + if hass.states.get(devicetracker_id) + else None + ) self._street_number = None self._street = None self._city = None @@ -356,31 +387,47 @@ def __init__(self, hass, devicetracker_id, name, api_key, options, home_zone, ma self._place_category = None self._place_neighbourhood = None self._home_latitude = home_latitude - self._home_longitude = home_longitude + self._home_longitude = home_longitude self._latitude_old = home_latitude self._longitude_old = home_longitude self._latitude = home_latitude self._longitude = home_longitude - self._devicetracker_zone = 'Home' - self._devicetracker_zone_name = 'Home' + self._devicetracker_zone = "Home" + self._devicetracker_zone_name = "Home" self._mtime = str(datetime.now()) self._distance_km = 0 self._distance_m = 0 - self._location_current = home_latitude + ',' + home_longitude - self._location_previous = home_latitude + ',' + home_longitude + self._location_current = home_latitude + "," + home_longitude + self._location_previous = home_latitude + "," + home_longitude self._updateskipped = 0 - self._direction = 'stationary' + self._direction = "stationary" self._map_link = None self._formatted_place = None #'https://www.google.com/maps/@' + home_latitude + "," + home_longitude + ',19z' # Check if devicetracker_id was specified correctly - _LOGGER.info( "(" + self._name + ") DeviceTracker Entity ID is " + devicetracker_id.split('.', 1)[1] ) - - if devicetracker_id.split('.', 1)[0] in TRACKABLE_DOMAINS: + _LOGGER.info( + "(" + + self._name + + ") DeviceTracker Entity ID is " + + devicetracker_id.split(".", 1)[1] + ) + + if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: self._devicetracker_id = devicetracker_id - track_state_change(hass, self._devicetracker_id, self.tsc_update, from_state=None, to_state=None) - _LOGGER.info( "(" + self._name + ") Now subscribed to state change events from " + self._devicetracker_id ) + track_state_change( + hass, + self._devicetracker_id, + self.tsc_update, + from_state=None, + to_state=None, + ) + _LOGGER.info( + "(" + + self._name + + ") Now subscribed to state change events from " + + self._devicetracker_id + ) @property def name(self): @@ -400,7 +447,7 @@ def entity_picture(self): @property def extra_state_attributes(self): """Return the state attributes.""" - return{ + return { ATTR_STREET_NUMBER: self._street_number, ATTR_STREET: self._street, ATTR_CITY: self._city, @@ -434,17 +481,16 @@ def extra_state_attributes(self): ATTR_DIRECTION_OF_TRAVEL: self._direction, ATTR_MAP_LINK: self._map_link, ATTR_OPTIONS: self._options, - ATTR_FORMATTED_PLACE: self._formatted_place + ATTR_FORMATTED_PLACE: self._formatted_place, } - def tsc_update(self, tscarg2, tsarg3, tsarg4): - """ Call the do_update function based on the TSC (track state change) event """ + """Call the do_update function based on the TSC (track state change) event""" self.do_update("Track State Change") @Throttle(THROTTLE_INTERVAL) def update(self): - """ Call the do_update function based on scan interval and throttle """ + """Call the do_update function based on scan interval and throttle""" self.do_update("Scan Interval") def haversine(self, lon1, lat1, lon2, lat2): @@ -452,15 +498,15 @@ def haversine(self, lon1, lat1, lon2, lat2): Calculate the great circle distance between two points on the earth (specified in decimal degrees) """ - # convert decimal degrees to radians + # convert decimal degrees to radians lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) - # haversine formula - dlon = lon2 - lon1 - dlat = lat2 - lat1 - a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 - c = 2 * asin(sqrt(a)) - r = 6371 # Radius of earth in kilometers. Use 3956 for miles + # haversine formula + dlon = lon2 - lon1 + dlat = lat2 - lat1 + a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2 + c = 2 * asin(sqrt(a)) + r = 6371 # Radius of earth in kilometers. Use 3956 for miles return c * r def do_update(self, reason): @@ -470,95 +516,203 @@ def do_update(self, reason): distance_traveled = 0 devicetracker_zone = None - _LOGGER.info( "(" + self._name + ") Calling update due to " + reason ) - _LOGGER.info( "(" + self._name + ") Check if update req'd : " + self._devicetracker_id ) - _LOGGER.debug( "(" + self._name + ") Previous State : " + previous_state ) + _LOGGER.info("(" + self._name + ") Calling update due to " + reason) + _LOGGER.info( + "(" + self._name + ") Check if update req'd : " + self._devicetracker_id + ) + _LOGGER.debug("(" + self._name + ") Previous State : " + previous_state) - if hasattr(self, '_devicetracker_id') and self.hass.states.get(self._devicetracker_id) is not None: + if ( + hasattr(self, "_devicetracker_id") + and self.hass.states.get(self._devicetracker_id) is not None + ): now = datetime.now() - old_latitude = str(self._latitude) - old_longitude = str(self._longitude) - new_latitude = str(self._hass.states.get(self._devicetracker_id).attributes.get('latitude')) - new_longitude = str(self._hass.states.get(self._devicetracker_id).attributes.get('longitude')) - home_latitude = str(self._home_latitude) - home_longitude = str(self._home_longitude) + old_latitude = str(self._latitude) + old_longitude = str(self._longitude) + new_latitude = str( + self._hass.states.get(self._devicetracker_id).attributes.get("latitude") + ) + new_longitude = str( + self._hass.states.get(self._devicetracker_id).attributes.get( + "longitude" + ) + ) + home_latitude = str(self._home_latitude) + home_longitude = str(self._home_longitude) last_distance_m = self._distance_m - last_updated = self._mtime - current_location = new_latitude + "," + new_longitude + last_updated = self._mtime + current_location = new_latitude + "," + new_longitude previous_location = old_latitude + "," + old_longitude - home_location = home_latitude + "," + home_longitude - - #maplink_google ='https://www.google.com/maps/@' + current_location+',' + self._map_zoom + 'z' - maplink_apple = 'https://maps.apple.com/maps/?q=' + current_location + '&z=' + self._map_zoom - #maplink_google = 'https://www.google.com/maps/dir/?api=1&origin=' + current_location + '&destination=' + home_location + '&travelmode=driving&layer=traffic' - maplink_google = 'https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=' + current_location - if (new_latitude != 'None' and new_longitude != 'None' and - home_latitude != 'None' and home_longitude != 'None'): - distance_m = distance(float(new_latitude), float(new_longitude), float(home_latitude), float(home_longitude)) - distance_km = round(distance_m / 1000, 2) - distance_from_home = str(distance_km)+' km' - - deviation = self.haversine(float(old_latitude), float(old_longitude), float(new_latitude), float(new_longitude)) - if deviation <= 0.2: # in kilometers - direction = "stationary" - elif last_distance_m > distance_m: - direction = "towards home" - elif last_distance_m < distance_m: - direction = "away from home" - else: - direction = "stationary" - - _LOGGER.debug( "(" + self._name + ") Previous Location: " + previous_location) - _LOGGER.debug( "(" + self._name + ") Current Location : " + current_location) - _LOGGER.debug( "(" + self._name + ") Home Location : " + home_location) - _LOGGER.info( "(" + self._name + ") Distance from home : (" + (self._home_zone).split(".")[1] + "): " + distance_from_home ) - _LOGGER.info( "(" + self._name + ") Travel Direction :(" + direction + ")" ) - - """Update if location has changed.""" - - - devicetracker_zone = self.hass.states.get(self._devicetracker_id).state - _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (before update): " + devicetracker_zone ) - - devicetracker_zone_id = self.hass.states.get(self._devicetracker_id).attributes.get('zone') - devicetracker_zone_id = 'zone.'+devicetracker_zone_id - _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone ID (before update): " + devicetracker_zone_id ) - - devicetracker_zone_name_state = self.hass.states.get(devicetracker_zone_id) - if devicetracker_zone_name_state: - devicetracker_zone_name = self.hass.states.get(devicetracker_zone_id).name - else: - devicetracker_zone_name = devicetracker_zone - _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone Name (before update): " + devicetracker_zone_name ) - - distance_traveled = distance(float(new_latitude), float(new_longitude), float(old_latitude), float(old_longitude)) - - _LOGGER.info( "(" + self._name + ") Meters traveled since last update: " + str(round(distance_traveled)) ) + home_location = home_latitude + "," + home_longitude + + # maplink_google ='https://www.google.com/maps/@' + current_location+',' + self._map_zoom + 'z' + maplink_apple = ( + "https://maps.apple.com/maps/?q=" + + current_location + + "&z=" + + self._map_zoom + ) + # maplink_google = 'https://www.google.com/maps/dir/?api=1&origin=' + current_location + '&destination=' + home_location + '&travelmode=driving&layer=traffic' + maplink_google = ( + "https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=" + + current_location + ) + if ( + new_latitude != "None" + and new_longitude != "None" + and home_latitude != "None" + and home_longitude != "None" + ): + distance_m = distance( + float(new_latitude), + float(new_longitude), + float(home_latitude), + float(home_longitude), + ) + distance_km = round(distance_m / 1000, 2) + distance_from_home = str(distance_km) + " km" + + deviation = self.haversine( + float(old_latitude), + float(old_longitude), + float(new_latitude), + float(new_longitude), + ) + if deviation <= 0.2: # in kilometers + direction = "stationary" + elif last_distance_m > distance_m: + direction = "towards home" + elif last_distance_m < distance_m: + direction = "away from home" + else: + direction = "stationary" + + _LOGGER.debug( + "(" + self._name + ") Previous Location: " + previous_location + ) + _LOGGER.debug( + "(" + self._name + ") Current Location : " + current_location + ) + _LOGGER.debug( + "(" + self._name + ") Home Location : " + home_location + ) + _LOGGER.info( + "(" + + self._name + + ") Distance from home : (" + + (self._home_zone).split(".")[1] + + "): " + + distance_from_home + ) + _LOGGER.info( + "(" + self._name + ") Travel Direction :(" + direction + ")" + ) + + """Update if location has changed.""" + + devicetracker_zone = self.hass.states.get(self._devicetracker_id).state + _LOGGER.info( + "(" + + self._name + + ") DeviceTracker Zone (before update): " + + devicetracker_zone + ) + + devicetracker_zone_id = self.hass.states.get( + self._devicetracker_id + ).attributes.get("zone") + devicetracker_zone_id = "zone." + devicetracker_zone_id + _LOGGER.debug( + "(" + + self._name + + ") DeviceTracker Zone ID (before update): " + + devicetracker_zone_id + ) + + devicetracker_zone_name_state = self.hass.states.get( + devicetracker_zone_id + ) + if devicetracker_zone_name_state: + devicetracker_zone_name = self.hass.states.get( + devicetracker_zone_id + ).name + else: + devicetracker_zone_name = devicetracker_zone + _LOGGER.debug( + "(" + + self._name + + ") DeviceTracker Zone Name (before update): " + + devicetracker_zone_name + ) + + distance_traveled = distance( + float(new_latitude), + float(new_longitude), + float(old_latitude), + float(old_longitude), + ) + + _LOGGER.info( + "(" + + self._name + + ") Meters traveled since last update: " + + str(round(distance_traveled)) + ) proceed_with_update = True if current_location == previous_location: - _LOGGER.debug( "(" + self._name + ") Skipping update because co-ordinates are identical" ) + _LOGGER.debug( + "(" + + self._name + + ") Skipping update because co-ordinates are identical" + ) proceed_with_update = False elif int(distance_traveled) > 0 and self._updateskipped > 3: proceed_with_update = True - _LOGGER.debug( "(" + self._name + ") Allowing update after 3 skips even with distance traveled < 10m" ) + _LOGGER.debug( + "(" + + self._name + + ") Allowing update after 3 skips even with distance traveled < 10m" + ) elif int(distance_traveled) < 10: self._updateskipped = self._updateskipped + 1 - _LOGGER.debug( "(" + self._name + ") Skipping update because location changed " + str(distance_traveled) + " < 10m (" + str(self._updateskipped) + ")" ) + _LOGGER.debug( + "(" + + self._name + + ") Skipping update because location changed " + + str(distance_traveled) + + " < 10m (" + + str(self._updateskipped) + + ")" + ) proceed_with_update = False - - if previous_state == 'Initializing...': - _LOGGER.debug( "(" + self._name + ") Peforming Initial Update for user at home..." ) + + if previous_state == "Initializing...": + _LOGGER.debug( + "(" + self._name + ") Peforming Initial Update for user at home..." + ) proceed_with_update = True if proceed_with_update and devicetracker_zone: - _LOGGER.debug( "(" + self._name + ") Proceeding with update for " + self._devicetracker_id ) + _LOGGER.debug( + "(" + + self._name + + ") Proceeding with update for " + + self._devicetracker_id + ) self._devicetracker_zone = devicetracker_zone - _LOGGER.info( "(" + self._name + ") DeviceTracker Zone (current) " + self._devicetracker_zone + " Skipped Updates: " + str(self._updateskipped)) + _LOGGER.info( + "(" + + self._name + + ") DeviceTracker Zone (current) " + + self._devicetracker_zone + + " Skipped Updates: " + + str(self._updateskipped) + ) self._reset_attributes() - + self._latitude = new_latitude self._longitude = new_longitude self._latitude_old = old_latitude @@ -571,44 +725,75 @@ def do_update(self, reason): self._distance_m = distance_m self._direction = direction - if self._map_provider == 'google': - _LOGGER.debug( "(" + self._name + ") Google Map Link requested for: [" + self._map_provider + "]") + if self._map_provider == "google": + _LOGGER.debug( + "(" + + self._name + + ") Google Map Link requested for: [" + + self._map_provider + + "]" + ) self._map_link = maplink_google else: - _LOGGER.debug( "(" + self._name + ") Apple Map Link requested for: [" + self._map_provider + "]") + _LOGGER.debug( + "(" + + self._name + + ") Apple Map Link requested for: [" + + self._map_provider + + "]" + ) self._map_link = maplink_apple - - _LOGGER.debug( "(" + self._name + ") Map Link generated: " + self._map_link ) - osm_url = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" + self._latitude + "&lon=" + self._longitude + ("&accept-language=" + self._language if self._language != DEFAULT_LANGUAGE else "") + "&addressdetails=1&namedetails=1&zoom=18&limit=1" + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") + _LOGGER.debug("(" + self._name + ") Map Link generated: " + self._map_link) + + osm_url = ( + "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" + + self._latitude + + "&lon=" + + self._longitude + + ( + "&accept-language=" + self._language + if self._language != DEFAULT_LANGUAGE + else "" + ) + + "&addressdetails=1&namedetails=1&zoom=18&limit=1" + + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") + ) osm_decoded = {} - _LOGGER.info( "(" + self._name + ") OpenStreetMap request sent with lat=" + self._latitude + " and lon=" + self._longitude) - _LOGGER.debug( "(" + self._name + ") url - " + osm_url) + _LOGGER.info( + "(" + + self._name + + ") OpenStreetMap request sent with lat=" + + self._latitude + + " and lon=" + + self._longitude + ) + _LOGGER.debug("(" + self._name + ") url - " + osm_url) osm_response = get(osm_url) osm_json_input = osm_response.text - _LOGGER.debug( "(" + self._name + ") response - " + osm_json_input) + _LOGGER.debug("(" + self._name + ") response - " + osm_json_input) osm_decoded = json.loads(osm_json_input) decoded = osm_decoded place_options = self._options.lower() - place_type = '-' - place_name = '-' - place_category = '-' - place_neighbourhood = '-' - street_number = '' - street = 'Unnamed Road' - city = '-' - postal_town = '-' - region = '-' - state_abbr = '-' - county = '-' - country = '-' - postal_code = '' - formatted_address = '' - target_option = '' - formatted_place = '' - + place_type = "-" + place_name = "-" + place_category = "-" + place_neighbourhood = "-" + street_number = "" + street = "Unnamed Road" + city = "-" + postal_town = "-" + region = "-" + state_abbr = "-" + county = "-" + country = "-" + postal_code = "" + formatted_address = "" + target_option = "" + formatted_place = "" + if "place" in self._options: place_type = osm_decoded["type"] if place_type == "yes": @@ -621,23 +806,23 @@ def do_update(self, reason): place_name = osm_decoded["address"][place_category] if "name" in osm_decoded["namedetails"]: place_name = osm_decoded["namedetails"]["name"] - for language in self._language.split(','): + for language in self._language.split(","): if "name:" + language in osm_decoded["namedetails"]: place_name = osm_decoded["namedetails"]["name:" + language] break - if self._devicetracker_zone == 'not_home' and place_name != 'house': + if self._devicetracker_zone == "not_home" and place_name != "house": new_state = place_name - + if "house_number" in osm_decoded["address"]: street_number = osm_decoded["address"]["house_number"] if "road" in osm_decoded["address"]: street = osm_decoded["address"]["road"] - + if "neighbourhood" in osm_decoded["address"]: place_neighbourhood = osm_decoded["address"]["neighbourhood"] elif "hamlet" in osm_decoded["address"]: place_neighbourhood = osm_decoded["address"]["hamlet"] - + if "city" in osm_decoded["address"]: city = osm_decoded["address"]["city"] elif "town" in osm_decoded["address"]: @@ -658,7 +843,9 @@ def do_update(self, reason): if "state" in osm_decoded["address"]: region = osm_decoded["address"]["state"] if "ISO3166-2-lvl4" in osm_decoded["address"]: - state_abbr = osm_decoded["address"]["ISO3166-2-lvl4"].split("-")[1].upper() + state_abbr = ( + osm_decoded["address"]["ISO3166-2-lvl4"].split("-")[1].upper() + ) if "county" in osm_decoded["address"]: county = osm_decoded["address"]["county"] if "country" in osm_decoded["address"]: @@ -672,7 +859,7 @@ def do_update(self, reason): self._place_category = place_category self._place_neighbourhood = place_neighbourhood self._place_name = place_name - + self._street_number = street_number self._street = street self._city = city @@ -684,66 +871,116 @@ def do_update(self, reason): self._postal_code = postal_code self._formatted_address = formatted_address self._mtime = str(datetime.now()) - + isDriving = False - + display_options = [] - options_array = self._options.split(',') + options_array = self._options.split(",") for option in options_array: - display_options.append(option.strip()) + display_options.append(option.strip()) # Formatted Place formatted_place_array = [] - if "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home": - if self._direction != 'stationary' and ( self._place_category == 'highway' or self._place_type == 'motorway' ) and "driving" in display_options: - formatted_place_array.append('Driving') + if ( + "stationary" in self._devicetracker_zone.lower() + or self._devicetracker_zone.lower() == "away" + or self._devicetracker_zone.lower() == "not_home" + ): + if ( + self._direction != "stationary" + and ( + self._place_category == "highway" + or self._place_type == "motorway" + ) + and "driving" in display_options + ): + formatted_place_array.append("Driving") isDriving = True - if self._place_name == '-': - if self._place_category == 'highway' and self._street == 'Unnamed Road': - formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").replace("-","").strip()+' '+self._place_category.title().strip()) - elif self._place_type == 'unclassified' or self._place_type == '-': - if self._place_category != '-': - formatted_place_array.append(self._place_category.title().strip()) + if self._place_name == "-": + if ( + self._place_category == "highway" + and self._street == "Unnamed Road" + ): + formatted_place_array.append( + self._place_type.title() + .replace("Proposed", "") + .replace("Construction", "") + .replace("-", "") + .strip() + + " " + + self._place_category.title().strip() + ) + elif self._place_type == "unclassified" or self._place_type == "-": + if self._place_category != "-": + formatted_place_array.append( + self._place_category.title().strip() + ) else: formatted_place_array.append(self._place_type.title().strip()) - if self._street != 'Unnamed Road': - formatted_place_array.append(self._street_number.replace("-","").strip()+' '+self._street.replace("-","").strip()) - elif self._place_neighbourhood != '-': - formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') + if self._street != "Unnamed Road": + formatted_place_array.append( + self._street_number.replace("-", "").strip() + + " " + + self._street.replace("-", "").strip() + ) + elif self._place_neighbourhood != "-": + formatted_place_array.append( + self._place_neighbourhood.strip() + " Neighborhood" + ) else: formatted_place_array.append(self._place_name.strip()) - if self._city != '-': - formatted_place_array.append(self._city.replace(" Township","").strip()) - elif self._county != '-': + if self._city != "-": + formatted_place_array.append( + self._city.replace(" Township", "").strip() + ) + elif self._county != "-": formatted_place_array.append(self._county.strip()) - if self._region != '-': + if self._region != "-": formatted_place_array.append(self._state_abbr) else: formatted_place_array.append(devicetracker_zone_name.strip()) - formatted_place = ', '.join( item for item in formatted_place_array) - formatted_place = formatted_place.replace('\n',' ').replace(' ',' ').strip() - self._formatted_place = formatted_place - - if 'error_message' in osm_decoded: - new_state = osm_decoded['error_message'] - _LOGGER.info( "(" + self._name + ") An error occurred contacting the web service") + formatted_place = ", ".join(item for item in formatted_place_array) + formatted_place = ( + formatted_place.replace("\n", " ").replace(" ", " ").strip() + ) + self._formatted_place = formatted_place + + if "error_message" in osm_decoded: + new_state = osm_decoded["error_message"] + _LOGGER.info( + "(" + self._name + ") An error occurred contacting the web service" + ) elif "formatted_place" in display_options: new_state = self._formatted_place - elif self._devicetracker_zone.lower() == "not_home" or "stationary" in self._devicetracker_zone.lower(): + elif ( + self._devicetracker_zone.lower() == "not_home" + or "stationary" in self._devicetracker_zone.lower() + ): # Options: "formatted_place, zone, zone_name, place, street_number, street, city, county, state, postal_code, country, formatted_address" - _LOGGER.debug( "(" + self._name + ") Building State from Display Options: " + self._options) - + _LOGGER.debug( + "(" + + self._name + + ") Building State from Display Options: " + + self._options + ) + user_display = [] - + if "driving" in display_options and isDriving: user_display.append("Driving") - if "zone_name" in display_options and "do_not_show_not_home" not in display_options: + if ( + "zone_name" in display_options + and "do_not_show_not_home" not in display_options + ): zone = self._devicetracker_zone user_display.append(self._devicetracker_zone_name) - elif "zone" in display_options and "do_not_show_not_home" not in display_options: + elif ( + "zone" in display_options + and "do_not_show_not_home" not in display_options + ): zone = self._devicetracker_zone user_display.append(self._devicetracker_zone) @@ -796,43 +1033,65 @@ def do_update(self, reason): user_display.append(street) user_display.append(city) - new_state = ', '.join( item for item in user_display ) - _LOGGER.debug( "(" + self._name + ") New State built from Display Options will be: " + new_state ) + new_state = ", ".join(item for item in user_display) + _LOGGER.debug( + "(" + + self._name + + ") New State built from Display Options will be: " + + new_state + ) elif "zone_name" in display_options: new_state = devicetracker_zone_name - _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker set to: " + new_state) + _LOGGER.debug( + "(" + + self._name + + ") New State from DeviceTracker set to: " + + new_state + ) else: new_state = devicetracker_zone - _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker set to: " + new_state) + _LOGGER.debug( + "(" + + self._name + + ") New State from DeviceTracker set to: " + + new_state + ) current_time = "%02d:%02d" % (now.hour, now.minute) - + if previous_state != new_state: - _LOGGER.info( "(" + self._name + ") New state built using options: " + self._options) - _LOGGER.debug( "(" + self._name + ") Building EventData for (" + new_state +")") - #new_state = new_state[:(255-14)] - #self._state = new_state + " (since " + current_time + ")" + _LOGGER.info( + "(" + + self._name + + ") New state built using options: " + + self._options + ) + _LOGGER.debug( + "(" + self._name + ") Building EventData for (" + new_state + ")" + ) + # new_state = new_state[:(255-14)] + # self._state = new_state + " (since " + current_time + ")" new_state = new_state[:255] self._state = new_state event_data = {} - event_data['entity'] = self._name - event_data['place_name'] = place_name - event_data['from_state'] = previous_state - event_data['to_state'] = new_state - event_data['distance_from_home'] = distance_from_home - event_data['direction'] = direction - event_data['devicetracker_zone'] = devicetracker_zone - event_data['devicetracker_zone_name'] = devicetracker_zone_name - event_data['latitude'] = self._latitude - event_data['longitude'] = self._longitude - event_data['previous_latitude'] = self._latitude_old - event_data['previous_longitude'] = self._longitude_old - event_data['map'] = self._map_link - event_data['mtime'] = current_time - #_LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) - #self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) - self._hass.bus.fire(DEFAULT_NAME+'_state_update', event_data ) - _LOGGER.debug( "(" + self._name + ") Update complete...") + event_data["entity"] = self._name + event_data["place_name"] = place_name + event_data["from_state"] = previous_state + event_data["to_state"] = new_state + event_data["distance_from_home"] = distance_from_home + event_data["direction"] = direction + event_data["devicetracker_zone"] = devicetracker_zone + event_data["devicetracker_zone_name"] = devicetracker_zone_name + event_data["latitude"] = self._latitude + event_data["longitude"] = self._longitude + event_data["previous_latitude"] = self._latitude_old + event_data["previous_longitude"] = self._longitude_old + event_data["map"] = self._map_link + event_data["mtime"] = current_time + # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) + # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) + self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) + _LOGGER.debug("(" + self._name + ") Update complete...") def _reset_attributes(self): """Resets attributes.""" From 13428715d800e3553edd1b060e78421d0e6be74d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 9 Aug 2022 23:32:13 -0400 Subject: [PATCH 030/329] Add GitHub Actions Create github-actions-demo.yml Create python_linter.yml Create pylint.yml Delete python_linter.yml Create python_linter.yml Delete github-actions-demo.yml Delete pylint.yml Create black_code_formatter.yml Update and rename python_linter.yml to my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml Update my_python_linter.yml --- .github/workflows/my_python_linter.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/my_python_linter.yml diff --git a/.github/workflows/my_python_linter.yml b/.github/workflows/my_python_linter.yml new file mode 100644 index 00000000..ed52c87f --- /dev/null +++ b/.github/workflows/my_python_linter.yml @@ -0,0 +1,22 @@ +name: My Python Linter (autoflake, isort, black) + +on: [workflow_dispatch, pull_request] + +jobs: + python_linter: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Black Code Formatter + uses: lgeiger/black-action@master + with: + args: ". --diff --color --check" + - uses: grantmcconnaughey/lintly-flake8-github-action@v1.0 + if: github.event_name == 'pull_request' + with: + # The GitHub API token to create reviews with + token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }} + # Fail if "new" violations detected or "any", default "new" + failIf: new + # Additional arguments to pass to flake8, default "." (current directory) + args: "." From 638cbd4bb8e68dce3478b3211411b945367ae62e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 10 Aug 2022 00:58:53 -0400 Subject: [PATCH 031/329] Update my_python_linter.yml --- .github/workflows/my_python_linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/my_python_linter.yml b/.github/workflows/my_python_linter.yml index ed52c87f..ac3e5079 100644 --- a/.github/workflows/my_python_linter.yml +++ b/.github/workflows/my_python_linter.yml @@ -17,6 +17,6 @@ jobs: # The GitHub API token to create reviews with token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }} # Fail if "new" violations detected or "any", default "new" - failIf: new + failIf: any # Additional arguments to pass to flake8, default "." (current directory) args: "." From 86935a6a5e7006f8326c8448c212c2c2d0b5c292 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 10 Aug 2022 01:03:21 -0400 Subject: [PATCH 032/329] Update my_python_linter.yml --- .github/workflows/my_python_linter.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/my_python_linter.yml b/.github/workflows/my_python_linter.yml index ac3e5079..aa894e69 100644 --- a/.github/workflows/my_python_linter.yml +++ b/.github/workflows/my_python_linter.yml @@ -7,10 +7,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - name: Black Code Formatter - uses: lgeiger/black-action@master - with: - args: ". --diff --color --check" + #- name: Black Code Formatter + # uses: lgeiger/black-action@master + # with: + # args: ". --diff --color --check" - uses: grantmcconnaughey/lintly-flake8-github-action@v1.0 if: github.event_name == 'pull_request' with: From 2a93c0431a38bd6cbdf4b662b308bc2f7ff6e56a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 10 Aug 2022 01:07:40 -0400 Subject: [PATCH 033/329] Update my_python_linter.yml --- .github/workflows/my_python_linter.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/my_python_linter.yml b/.github/workflows/my_python_linter.yml index aa894e69..9d07f421 100644 --- a/.github/workflows/my_python_linter.yml +++ b/.github/workflows/my_python_linter.yml @@ -6,17 +6,16 @@ jobs: python_linter: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 #- name: Black Code Formatter # uses: lgeiger/black-action@master # with: # args: ". --diff --color --check" - - uses: grantmcconnaughey/lintly-flake8-github-action@v1.0 - if: github.event_name == 'pull_request' + - uses: sailingpalmtree/lint@latest with: - # The GitHub API token to create reviews with - token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }} - # Fail if "new" violations detected or "any", default "new" - failIf: any - # Additional arguments to pass to flake8, default "." (current directory) - args: "." + github_token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }} + # Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review]. + reporter: github-pr-review + # Change reporter level if you need. + # GitHub Status Check won't become failure with warning. + level: warning From 60ae37a6cb33693afc9cb223ecf2191e3019b22e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 12 Aug 2022 17:48:27 -0400 Subject: [PATCH 034/329] Refine Formatted Place Sensor --- custom_components/places/sensor.py | 43 +++++++++--------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5ac6610e..a8a0b25e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -896,37 +896,18 @@ def do_update(self, reason): ): formatted_place_array.append("Driving") isDriving = True - if self._place_name == "-": - if ( - self._place_category == "highway" - and self._street == "Unnamed Road" - ): - formatted_place_array.append( - self._place_type.title() - .replace("Proposed", "") - .replace("Construction", "") - .replace("-", "") - .strip() - + " " - + self._place_category.title().strip() - ) - elif self._place_type == "unclassified" or self._place_type == "-": - if self._place_category != "-": - formatted_place_array.append( - self._place_category.title().strip() - ) - else: - formatted_place_array.append(self._place_type.title().strip()) - if self._street != "Unnamed Road": - formatted_place_array.append( - self._street_number.replace("-", "").strip() - + " " - + self._street.replace("-", "").strip() - ) - elif self._place_neighbourhood != "-": - formatted_place_array.append( - self._place_neighbourhood.strip() + " Neighborhood" - ) + if self._place_name == '-': + if self._place_neighbourhood != '-': + formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') + elif self._place_type != '-' and self._place_type.lower() != 'unclassified': + formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").strip()+' '+self._place_category.title().strip()) + elif self._place_category != '-': + formatted_place_array.append(self._place_category.title().strip()) + if self._street.lower() != 'unnamed road' and self._street != '-': + if self._street_number == '-': + formatted_place_array.append(self._street.strip()) + else: + formatted_place_array.append(self._street_number.strip()+' '+self._street.strip()) else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From 58aeb1679b4d68b0bf2b69c4cb34a088a5d9e39d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 12 Aug 2022 17:53:36 -0400 Subject: [PATCH 035/329] Black Code Formatting --- custom_components/places/sensor.py | 36 +++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a8a0b25e..a983de86 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -896,18 +896,34 @@ def do_update(self, reason): ): formatted_place_array.append("Driving") isDriving = True - if self._place_name == '-': - if self._place_neighbourhood != '-': - formatted_place_array.append(self._place_neighbourhood.strip()+' Neighborhood') - elif self._place_type != '-' and self._place_type.lower() != 'unclassified': - formatted_place_array.append(self._place_type.title().replace("Proposed","").replace("Construction","").strip()+' '+self._place_category.title().strip()) - elif self._place_category != '-': - formatted_place_array.append(self._place_category.title().strip()) - if self._street.lower() != 'unnamed road' and self._street != '-': - if self._street_number == '-': + if self._place_name == "-": + if self._place_neighbourhood != "-": + formatted_place_array.append( + self._place_neighbourhood.strip() + " Neighborhood" + ) + elif ( + self._place_type != "-" + and self._place_type.lower() != "unclassified" + ): + formatted_place_array.append( + self._place_type.title() + .replace("Proposed", "") + .replace("Construction", "") + .strip() + + " " + + self._place_category.title().strip() + ) + elif self._place_category != "-": + formatted_place_array.append( + self._place_category.title().strip() + ) + if self._street.lower() != "unnamed road" and self._street != "-": + if self._street_number == "-": formatted_place_array.append(self._street.strip()) else: - formatted_place_array.append(self._street_number.strip()+' '+self._street.strip()) + formatted_place_array.append( + self._street_number.strip() + " " + self._street.strip() + ) else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From aa3a23deabdca1a105a1e9fdb26dd8f432f02a8e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 12 Aug 2022 19:06:18 -0400 Subject: [PATCH 036/329] Add OSM ID and Type --- custom_components/places/sensor.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5ac6610e..87be285b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -279,6 +279,8 @@ ATTR_DIRECTION_OF_TRAVEL = "direction_of_travel" ATTR_MAP_LINK = "map_link" ATTR_FORMATTED_PLACE = "formatted_place" +ATTR_OSM_ID = 'osm_id' +ATTR_OSM_TYPE = 'osm_type' DEFAULT_NAME = "places" DEFAULT_OPTION = "zone, place" @@ -403,6 +405,8 @@ def __init__( self._direction = "stationary" self._map_link = None self._formatted_place = None + self._osm_id = None + self._osm_type = None #'https://www.google.com/maps/@' + home_latitude + "," + home_longitude + ',19z' # Check if devicetracker_id was specified correctly @@ -482,6 +486,8 @@ def extra_state_attributes(self): ATTR_MAP_LINK: self._map_link, ATTR_OPTIONS: self._options, ATTR_FORMATTED_PLACE: self._formatted_place, + ATTR_OSM_ID: self._osm_id, + ATTR_OSM_TYPE: self._osm_type, } def tsc_update(self, tscarg2, tsarg3, tsarg4): @@ -855,6 +861,11 @@ def do_update(self, reason): if "display_name" in osm_decoded: formatted_address = osm_decoded["display_name"] + if "osm_id" in osm_decoded: + osm_id = osm_decoded["osm_id"] + if "osm_type" in osm_decoded: + osm_type = osm_decoded["osm_type"] + self._place_type = place_type self._place_category = place_category self._place_neighbourhood = place_neighbourhood @@ -871,6 +882,8 @@ def do_update(self, reason): self._postal_code = postal_code self._formatted_address = formatted_address self._mtime = str(datetime.now()) + self._osm_id = osm_id + self._osm_type = osm_type isDriving = False @@ -1088,6 +1101,8 @@ def do_update(self, reason): event_data["previous_longitude"] = self._longitude_old event_data["map"] = self._map_link event_data["mtime"] = current_time + event_data['osm_id'] = osm_id + event_data['osm_type'] = osm_type # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) @@ -1108,4 +1123,6 @@ def _reset_attributes(self): self._place_type = None self._place_name = None self._mtime = datetime.now() + self._osm_id = None + self._osm_type = None self._updateskipped = 0 From ac5202c35302eb34ffe92ebad5db7660f64755a6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 12 Aug 2022 19:10:03 -0400 Subject: [PATCH 037/329] Black Code Formatting --- custom_components/places/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 87be285b..d0e8f127 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -279,8 +279,8 @@ ATTR_DIRECTION_OF_TRAVEL = "direction_of_travel" ATTR_MAP_LINK = "map_link" ATTR_FORMATTED_PLACE = "formatted_place" -ATTR_OSM_ID = 'osm_id' -ATTR_OSM_TYPE = 'osm_type' +ATTR_OSM_ID = "osm_id" +ATTR_OSM_TYPE = "osm_type" DEFAULT_NAME = "places" DEFAULT_OPTION = "zone, place" @@ -1101,8 +1101,8 @@ def do_update(self, reason): event_data["previous_longitude"] = self._longitude_old event_data["map"] = self._map_link event_data["mtime"] = current_time - event_data['osm_id'] = osm_id - event_data['osm_type'] = osm_type + event_data["osm_id"] = osm_id + event_data["osm_type"] = osm_type # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) From d1c190808645b9f6a896e9f952a9f83bea9e1779 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 12 Aug 2022 21:00:33 -0400 Subject: [PATCH 038/329] Add OSM Details Dict --- custom_components/places/sensor.py | 51 +++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5d8ae076..b697fa24 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -281,6 +281,7 @@ ATTR_FORMATTED_PLACE = "formatted_place" ATTR_OSM_ID = "osm_id" ATTR_OSM_TYPE = "osm_type" +ATTR_OSM_DETAILS_DICT ="osm_details_dict" DEFAULT_NAME = "places" DEFAULT_OPTION = "zone, place" @@ -407,6 +408,7 @@ def __init__( self._formatted_place = None self._osm_id = None self._osm_type = None + self._osm_details_dict = None #'https://www.google.com/maps/@' + home_latitude + "," + home_longitude + ',19z' # Check if devicetracker_id was specified correctly @@ -488,6 +490,7 @@ def extra_state_attributes(self): ATTR_FORMATTED_PLACE: self._formatted_place, ATTR_OSM_ID: self._osm_id, ATTR_OSM_TYPE: self._osm_type, + ATTR_OSM_DETAILS_dict: self._osm_details_dict, } def tsc_update(self, tscarg2, tsarg3, tsarg4): @@ -775,12 +778,12 @@ def do_update(self, reason): + " and lon=" + self._longitude ) - _LOGGER.debug("(" + self._name + ") url - " + osm_url) + _LOGGER.debug("(" + self._name + ") OSM URL - " + osm_url) osm_response = get(osm_url) osm_json_input = osm_response.text - _LOGGER.debug("(" + self._name + ") response - " + osm_json_input) + _LOGGER.debug("(" + self._name + ") OSM Response - " + osm_json_input) osm_decoded = json.loads(osm_json_input) - decoded = osm_decoded + #decoded = osm_decoded place_options = self._options.lower() place_type = "-" @@ -862,7 +865,7 @@ def do_update(self, reason): formatted_address = osm_decoded["display_name"] if "osm_id" in osm_decoded: - osm_id = osm_decoded["osm_id"] + osm_id = str(osm_decoded["osm_id"]) if "osm_type" in osm_decoded: osm_type = osm_decoded["osm_type"] @@ -882,7 +885,7 @@ def do_update(self, reason): self._postal_code = postal_code self._formatted_address = formatted_address self._mtime = str(datetime.now()) - self._osm_id = osm_id + self._osm_id = str(osm_id) self._osm_type = osm_type isDriving = False @@ -1067,6 +1070,42 @@ def do_update(self, reason): + new_state ) + osm_details_decoded = {} + if osm_id is not None and osm_type is not None: + if osm_type.lower() == 'node': + osm_type_abbr = 'N' + elif osm_type.lower() == 'way': + osm_type_abbr = 'W' + elif osm_type.lower() == 'relation': + osm_type_abbr = 'R' + + osm_details_url = ( + "https://nominatim.openstreetmap.org/details.php?osmtype=" + + osm_type_abbr + + "&osmid=" + + osm_id + + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" + + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") + ) + + _LOGGER.info( + "(" + + self._name + + ") OpenStreetMap Details request sent with type=" + + osm_type + + " (" + + osm_type_abbr + + ") and id=" + + str(osm_id) + ) + _LOGGER.debug("(" + self._name + ") OSM Details URL - " + osm_details_url) + osm_details_response = get(osm_details_url) + osm_details_json_input = osm_details_response.text + osm_details_decoded = json.loads(osm_details_json_input) + _LOGGER.debug("(" + self._name + ") OSM Details JSON - " + osm_details_json_input) + #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_decoded)) + self._osm_details_dict = osm_details_decoded + current_time = "%02d:%02d" % (now.hour, now.minute) if previous_state != new_state: @@ -1100,6 +1139,7 @@ def do_update(self, reason): event_data["mtime"] = current_time event_data["osm_id"] = osm_id event_data["osm_type"] = osm_type + event_data["osm_details_dict"] = self._osm_details_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) @@ -1122,4 +1162,5 @@ def _reset_attributes(self): self._mtime = datetime.now() self._osm_id = None self._osm_type = None + self._osm_details_dict = None self._updateskipped = 0 From 6c888045a58e524145b1f8c7e4652b6fea8e0d80 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 09:11:36 -0400 Subject: [PATCH 039/329] Add OSM Dict and Wikidata Dict too --- custom_components/places/sensor.py | 57 ++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b697fa24..01c53bce 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -281,7 +281,10 @@ ATTR_FORMATTED_PLACE = "formatted_place" ATTR_OSM_ID = "osm_id" ATTR_OSM_TYPE = "osm_type" -ATTR_OSM_DETAILS_DICT ="osm_details_dict" +ATTR_WIKIDATA_ID = "wikidata_id" +ATTR_OSM_DICT = "osm_dict" +ATTR_OSM_DETAILS_DICT = "osm_details_dict" +ATTR_WIKIDATA_DICT = "wikidata_dict" DEFAULT_NAME = "places" DEFAULT_OPTION = "zone, place" @@ -408,7 +411,10 @@ def __init__( self._formatted_place = None self._osm_id = None self._osm_type = None + self._wikidata_id = None + self._osm_dict = None self._osm_details_dict = None + self._wikidata_dict = None #'https://www.google.com/maps/@' + home_latitude + "," + home_longitude + ',19z' # Check if devicetracker_id was specified correctly @@ -490,7 +496,10 @@ def extra_state_attributes(self): ATTR_FORMATTED_PLACE: self._formatted_place, ATTR_OSM_ID: self._osm_id, ATTR_OSM_TYPE: self._osm_type, - ATTR_OSM_DETAILS_dict: self._osm_details_dict, + ATTR_WIKIDATA_ID: self._wikidata_id, + ATTR_OSM_DICT: self._osm_dict, + ATTR_OSM_DETAILS_DICT: self._osm_details_dict, + ATTR_WIKIDATA_DICT: self._wikidata_dict, } def tsc_update(self, tscarg2, tsarg3, tsarg4): @@ -1070,7 +1079,9 @@ def do_update(self, reason): + new_state ) - osm_details_decoded = {} + self._osm_dict = osm_decoded + + osm_details_dict = {} if osm_id is not None and osm_type is not None: if osm_type.lower() == 'node': osm_type_abbr = 'N' @@ -1101,10 +1112,36 @@ def do_update(self, reason): _LOGGER.debug("(" + self._name + ") OSM Details URL - " + osm_details_url) osm_details_response = get(osm_details_url) osm_details_json_input = osm_details_response.text - osm_details_decoded = json.loads(osm_details_json_input) + osm_details_dict = json.loads(osm_details_json_input) _LOGGER.debug("(" + self._name + ") OSM Details JSON - " + osm_details_json_input) - #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_decoded)) - self._osm_details_dict = osm_details_decoded + #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) + self._osm_details_dict = osm_details_dict + + #Make this work + wikidata_id = "Q178114" + self._wikidata_id = wikidata_id + + wikidata_decoded = {} + if wikidata_id is not None: + wikidata_url = ( + "https://www.wikidata.org/wiki/Special:EntityData/" + + wikidata_id + + ".json" + ) + + _LOGGER.info( + "(" + + self._name + + ") Wikidata request sent with id=" + + wikidata_id + ) + _LOGGER.debug("(" + self._name + ") Wikidata URL - " + wikidata_url) + wikidata_response = get(wikidata_url) + wikidata_json_input = wikidata_response.text + wikidata_dict = json.loads(wikidata_json_input) + _LOGGER.debug("(" + self._name + ") Wikidata JSON - " + wikidata_json_input) + _LOGGER.debug("(" + self._name + ") Wikidata Dict - " + str(wikidata_dict)) + self._wikidata_dict = wikidata_dict current_time = "%02d:%02d" % (now.hour, now.minute) @@ -1139,7 +1176,10 @@ def do_update(self, reason): event_data["mtime"] = current_time event_data["osm_id"] = osm_id event_data["osm_type"] = osm_type - event_data["osm_details_dict"] = self._osm_details_dict + event_data["wikidata_id"] = wikidata_id + event_data["osm_dict"] = osm_dict + event_data["osm_details_dict"] = osm_details_dict + event_data["wikidata_dict"] = wikidata_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) @@ -1162,5 +1202,8 @@ def _reset_attributes(self): self._mtime = datetime.now() self._osm_id = None self._osm_type = None + self._wikidata_id = None + self._osm_dict = None self._osm_details_dict = None + self._wikidata_dict = None self._updateskipped = 0 From 84b39be7d5d40bf487553d374dd9c2e064a9bca3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 09:15:43 -0400 Subject: [PATCH 040/329] Only call extended APIs if there is a state change --- custom_components/places/sensor.py | 114 ++++++++++++++--------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 01c53bce..94b80770 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1080,72 +1080,72 @@ def do_update(self, reason): ) self._osm_dict = osm_decoded - - osm_details_dict = {} - if osm_id is not None and osm_type is not None: - if osm_type.lower() == 'node': - osm_type_abbr = 'N' - elif osm_type.lower() == 'way': - osm_type_abbr = 'W' - elif osm_type.lower() == 'relation': - osm_type_abbr = 'R' - - osm_details_url = ( - "https://nominatim.openstreetmap.org/details.php?osmtype=" - + osm_type_abbr - + "&osmid=" - + osm_id - + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" - + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") - ) + current_time = "%02d:%02d" % (now.hour, now.minute) - _LOGGER.info( - "(" - + self._name - + ") OpenStreetMap Details request sent with type=" - + osm_type - + " (" - + osm_type_abbr - + ") and id=" - + str(osm_id) - ) - _LOGGER.debug("(" + self._name + ") OSM Details URL - " + osm_details_url) - osm_details_response = get(osm_details_url) - osm_details_json_input = osm_details_response.text - osm_details_dict = json.loads(osm_details_json_input) - _LOGGER.debug("(" + self._name + ") OSM Details JSON - " + osm_details_json_input) - #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) - self._osm_details_dict = osm_details_dict - - #Make this work - wikidata_id = "Q178114" - self._wikidata_id = wikidata_id - - wikidata_decoded = {} - if wikidata_id is not None: - wikidata_url = ( - "https://www.wikidata.org/wiki/Special:EntityData/" - + wikidata_id - + ".json" + if previous_state != new_state: + + osm_details_dict = {} + if osm_id is not None and osm_type is not None: + if osm_type.lower() == 'node': + osm_type_abbr = 'N' + elif osm_type.lower() == 'way': + osm_type_abbr = 'W' + elif osm_type.lower() == 'relation': + osm_type_abbr = 'R' + + osm_details_url = ( + "https://nominatim.openstreetmap.org/details.php?osmtype=" + + osm_type_abbr + + "&osmid=" + + osm_id + + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" + + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") ) _LOGGER.info( "(" + self._name - + ") Wikidata request sent with id=" - + wikidata_id + + ") OpenStreetMap Details request sent with type=" + + osm_type + + " (" + + osm_type_abbr + + ") and id=" + + str(osm_id) ) - _LOGGER.debug("(" + self._name + ") Wikidata URL - " + wikidata_url) - wikidata_response = get(wikidata_url) - wikidata_json_input = wikidata_response.text - wikidata_dict = json.loads(wikidata_json_input) - _LOGGER.debug("(" + self._name + ") Wikidata JSON - " + wikidata_json_input) - _LOGGER.debug("(" + self._name + ") Wikidata Dict - " + str(wikidata_dict)) - self._wikidata_dict = wikidata_dict + _LOGGER.debug("(" + self._name + ") OSM Details URL - " + osm_details_url) + osm_details_response = get(osm_details_url) + osm_details_json_input = osm_details_response.text + osm_details_dict = json.loads(osm_details_json_input) + _LOGGER.debug("(" + self._name + ") OSM Details JSON - " + osm_details_json_input) + #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) + self._osm_details_dict = osm_details_dict + + #Make this work + wikidata_id = "Q178114" + self._wikidata_id = wikidata_id + + wikidata_decoded = {} + if wikidata_id is not None: + wikidata_url = ( + "https://www.wikidata.org/wiki/Special:EntityData/" + + wikidata_id + + ".json" + ) - current_time = "%02d:%02d" % (now.hour, now.minute) + _LOGGER.info( + "(" + + self._name + + ") Wikidata request sent with id=" + + wikidata_id + ) + _LOGGER.debug("(" + self._name + ") Wikidata URL - " + wikidata_url) + wikidata_response = get(wikidata_url) + wikidata_json_input = wikidata_response.text + wikidata_dict = json.loads(wikidata_json_input) + _LOGGER.debug("(" + self._name + ") Wikidata JSON - " + wikidata_json_input) + _LOGGER.debug("(" + self._name + ") Wikidata Dict - " + str(wikidata_dict)) + self._wikidata_dict = wikidata_dict - if previous_state != new_state: _LOGGER.info( "(" + self._name From d3d66df26f8010adf291bf605981b22702e4f80e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 10:12:34 -0400 Subject: [PATCH 041/329] Make it an integration option --- custom_components/places/sensor.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 94b80770..d0fd1311 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -244,6 +244,7 @@ CONF_MAP_PROVIDER = "map_provider" CONF_MAP_ZOOM = "map_zoom" CONF_LANGUAGE = "language" +CONF_EXTENDED_ATTR = "extended_attr" ATTR_OPTIONS = "options" ATTR_STREET_NUMBER = "street_number" @@ -293,6 +294,7 @@ DEFAULT_MAP_PROVIDER = "apple" DEFAULT_MAP_ZOOM = "18" DEFAULT_LANGUAGE = "default" +DEFAULT_EXTENDED_ATTR = False SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) @@ -308,6 +310,7 @@ vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.string, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, } ) @@ -324,6 +327,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): map_provider = config.get(CONF_MAP_PROVIDER) map_zoom = config.get(CONF_MAP_ZOOM) language = config.get(CONF_LANGUAGE) + extended_attr = config.get(CONF_EXTENDED_ATTR) add_devices( [ @@ -337,6 +341,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): map_provider, map_zoom, language, + extended_attr, ) ] ) @@ -356,6 +361,7 @@ def __init__( map_provider, map_zoom, language, + extended_attr, ): """Initialize the sensor.""" self._hass = hass @@ -368,6 +374,7 @@ def __init__( self._map_zoom = map_zoom.lower() self._language = language.lower() self._language.replace(" ", "") + self._extended_attr = extended_attr self._state = "Initializing... (since 99:99)" home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) @@ -1176,10 +1183,11 @@ def do_update(self, reason): event_data["mtime"] = current_time event_data["osm_id"] = osm_id event_data["osm_type"] = osm_type - event_data["wikidata_id"] = wikidata_id - event_data["osm_dict"] = osm_dict - event_data["osm_details_dict"] = osm_details_dict - event_data["wikidata_dict"] = wikidata_dict + if self._extended_attr: + event_data["wikidata_id"] = wikidata_id + event_data["osm_dict"] = osm_dict + event_data["osm_details_dict"] = osm_details_dict + event_data["wikidata_dict"] = wikidata_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) From 174b220690fcdcdd72e80b7d4ba96647201759cc Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 11:36:43 -0400 Subject: [PATCH 042/329] Don't show attribute if None Won't affect ones set as '-' ...... for now. Further limit API queries if not needed Fix typo --- custom_components/places/sensor.py | 294 +++++++++++++++++------------ 1 file changed, 178 insertions(+), 116 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index d0fd1311..28cd6ba4 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -466,48 +466,90 @@ def entity_picture(self): @property def extra_state_attributes(self): """Return the state attributes.""" - return { - ATTR_STREET_NUMBER: self._street_number, - ATTR_STREET: self._street, - ATTR_CITY: self._city, - ATTR_POSTAL_TOWN: self._postal_town, - ATTR_POSTAL_CODE: self._postal_code, - ATTR_REGION: self._region, - ATTR_STATE_ABBR: self._state_abbr, - ATTR_COUNTRY: self._country, - ATTR_COUNTY: self._county, - ATTR_FORMATTED_ADDRESS: self._formatted_address, - ATTR_PLACE_TYPE: self._place_type, - ATTR_PLACE_NAME: self._place_name, - ATTR_PLACE_CATEGORY: self._place_category, - ATTR_PLACE_NEIGHBOURHOOD: self._place_neighbourhood, - ATTR_LATITUDE_OLD: self._latitude_old, - ATTR_LONGITUDE_OLD: self._longitude_old, - ATTR_LATITUDE: self._latitude, - ATTR_LONGITUDE: self._longitude, - ATTR_DEVICETRACKER_ID: self._devicetracker_id, - ATTR_DEVICETRACKER_ZONE: self._devicetracker_zone, - ATTR_DEVICETRACKER_ZONE_NAME: self._devicetracker_zone_name, - ATTR_HOME_ZONE: self._home_zone, - ATTR_PICTURE: self._entity_picture, - ATTR_DISTANCE_KM: self._distance_km, - ATTR_DISTANCE_M: self._distance_m, - ATTR_MTIME: self._mtime, - ATTR_LOCATION_CURRENT: self._location_current, - ATTR_LOCATION_PREVIOUS: self._location_previous, - ATTR_HOME_LATITUDE: self._home_latitude, - ATTR_HOME_LONGITUDE: self._home_longitude, - ATTR_DIRECTION_OF_TRAVEL: self._direction, - ATTR_MAP_LINK: self._map_link, - ATTR_OPTIONS: self._options, - ATTR_FORMATTED_PLACE: self._formatted_place, - ATTR_OSM_ID: self._osm_id, - ATTR_OSM_TYPE: self._osm_type, - ATTR_WIKIDATA_ID: self._wikidata_id, - ATTR_OSM_DICT: self._osm_dict, - ATTR_OSM_DETAILS_DICT: self._osm_details_dict, - ATTR_WIKIDATA_DICT: self._wikidata_dict, - } + return_attr = {} + + if self._street_number is not None: + return_attr[ATTR_STREET_NUMBER] = self._street_number + if self._street is not None: + return_attr[ATTR_STREET] = self._street + if self._city is not None: + return_attr[ATTR_CITY] = self._city + if self._postal_town is not None: + return_attr[ATTR_POSTAL_TOWN] = self._postal_town + if self._postal_code is not None: + return_attr[ATTR_POSTAL_CODE] = self._postal_code + if self._region is not None: + return_attr[ATTR_REGION] = self._region + if self._state_abbr is not None: + return_attr[ATTR_STATE_ABBR] = self._state_abbr + if self._country is not None: + return_attr[ATTR_COUNTRY] = self._country + if self._county is not None: + return_attr[ATTR_COUNTY] = self._county + if self._formatted_address is not None: + return_attr[ATTR_FORMATTED_ADDRESS] = self._formatted_address + if self._place_type is not None: + return_attr[ATTR_PLACE_TYPE] = self._place_type + if self._place_name is not None: + return_attr[ATTR_PLACE_NAME] = self._place_name + if self._place_category is not None: + return_attr[ATTR_PLACE_CATEGORY] = self._place_category + if self._place_neighbourhood is not None: + return_attr[ATTR_PLACE_NEIGHBOURHOOD] = self._place_neighbourhood + if self._formatted_place is not None: + return_attr[ATTR_FORMATTED_PLACE] = self._formatted_place + if self._latitude_old is not None: + return_attr[ATTR_LATITUDE_OLD] = self._latitude_old + if self._longitude_old is not None: + return_attr[ATTR_LONGITUDE_OLD] = self._longitude_old + if self._latitude is not None: + return_attr[ATTR_LATITUDE] = self._latitude + if self._longitude is not None: + return_attr[ATTR_LONGITUDE] = self._longitude + if self._devicetracker_id is not None: + return_attr[ATTR_DEVICETRACKER_ID] = self._devicetracker_id + if self._devicetracker_zone is not None: + return_attr[ATTR_DEVICETRACKER_ZONE] = self._devicetracker_zone + if self._devicetracker_zone_name is not None: + return_attr[ATTR_DEVICETRACKER_ZONE_NAME] = self._devicetracker_zone_name + if self._home_zone is not None: + return_attr[ATTR_HOME_ZONE] = self._home_zone + if self._entity_picture is not None: + return_attr[ATTR_PICTURE] = self._entity_picture + if self._distance_km is not None: + return_attr[ATTR_DISTANCE_KM] = self._distance_km + if self._distance_m is not None: + return_attr[ATTR_DISTANCE_M] = self._distance_m + if self._mtime is not None: + return_attr[ATTR_MTIME] = self._mtime + if self._location_current is not None: + return_attr[ATTR_LOCATION_CURRENT] = self._location_current + if self._location_previous is not None: + return_attr[ATTR_LOCATION_PREVIOUS] = self._location_previous + if self._home_latitude is not None: + return_attr[ATTR_HOME_LATITUDE] = self._home_latitude + if self._home_longitude is not None: + return_attr[ATTR_HOME_LONGITUDE] = self._home_longitude + if self._direction is not None: + return_attr[ATTR_DIRECTION_OF_TRAVEL] = self._direction + if self._map_link is not None: + return_attr[ATTR_MAP_LINK] = self._map_link + if self._options is not None: + return_attr[ATTR_OPTIONS] = self._options + if self._osm_id is not None: + return_attr[ATTR_OSM_ID] = self._osm_id + if self._osm_type is not None: + return_attr[ATTR_OSM_TYPE] = self._osm_type + if self._wikidata_id is not None: + return_attr[ATTR_WIKIDATA_ID] = self._wikidata_id + if self._osm_dict is not None: + return_attr[ATTR_OSM_DICT] = self._osm_dict + if self._osm_details_dict is not None: + return_attr[ATTR_OSM_DETAILS_DICT] = self._osm_details_dict + if self._wikidata_dict is not None: + return_attr[ATTR_WIKIDATA_DICT] = self._wikidata_dict + #_LOGGER.debug("(" + self._name + ") Extra State Attributes - " + return_attr) + return return_attr def tsc_update(self, tscarg2, tsarg3, tsarg4): """Call the do_update function based on the TSC (track state change) event""" @@ -1085,73 +1127,75 @@ def do_update(self, reason): + ") New State from DeviceTracker set to: " + new_state ) - - self._osm_dict = osm_decoded + + if self._extended_attr: + self._osm_dict = osm_decoded current_time = "%02d:%02d" % (now.hour, now.minute) if previous_state != new_state: - osm_details_dict = {} - if osm_id is not None and osm_type is not None: - if osm_type.lower() == 'node': - osm_type_abbr = 'N' - elif osm_type.lower() == 'way': - osm_type_abbr = 'W' - elif osm_type.lower() == 'relation': - osm_type_abbr = 'R' - - osm_details_url = ( - "https://nominatim.openstreetmap.org/details.php?osmtype=" - + osm_type_abbr - + "&osmid=" - + osm_id - + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" - + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") - ) - - _LOGGER.info( - "(" - + self._name - + ") OpenStreetMap Details request sent with type=" - + osm_type - + " (" - + osm_type_abbr - + ") and id=" - + str(osm_id) - ) - _LOGGER.debug("(" + self._name + ") OSM Details URL - " + osm_details_url) - osm_details_response = get(osm_details_url) - osm_details_json_input = osm_details_response.text - osm_details_dict = json.loads(osm_details_json_input) - _LOGGER.debug("(" + self._name + ") OSM Details JSON - " + osm_details_json_input) - #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) - self._osm_details_dict = osm_details_dict - - #Make this work - wikidata_id = "Q178114" - self._wikidata_id = wikidata_id - - wikidata_decoded = {} - if wikidata_id is not None: - wikidata_url = ( - "https://www.wikidata.org/wiki/Special:EntityData/" - + wikidata_id - + ".json" + if self._extended_attr: + osm_details_dict = {} + if osm_id is not None and osm_type is not None: + if osm_type.lower() == 'node': + osm_type_abbr = 'N' + elif osm_type.lower() == 'way': + osm_type_abbr = 'W' + elif osm_type.lower() == 'relation': + osm_type_abbr = 'R' + + osm_details_url = ( + "https://nominatim.openstreetmap.org/details.php?osmtype=" + + osm_type_abbr + + "&osmid=" + + osm_id + + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" + + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") ) _LOGGER.info( "(" + self._name - + ") Wikidata request sent with id=" - + wikidata_id + + ") OpenStreetMap Details request sent with type=" + + osm_type + + " (" + + osm_type_abbr + + ") and id=" + + str(osm_id) ) - _LOGGER.debug("(" + self._name + ") Wikidata URL - " + wikidata_url) - wikidata_response = get(wikidata_url) - wikidata_json_input = wikidata_response.text - wikidata_dict = json.loads(wikidata_json_input) - _LOGGER.debug("(" + self._name + ") Wikidata JSON - " + wikidata_json_input) - _LOGGER.debug("(" + self._name + ") Wikidata Dict - " + str(wikidata_dict)) - self._wikidata_dict = wikidata_dict + _LOGGER.debug("(" + self._name + ") OSM Details URL - " + osm_details_url) + osm_details_response = get(osm_details_url) + osm_details_json_input = osm_details_response.text + osm_details_dict = json.loads(osm_details_json_input) + _LOGGER.debug("(" + self._name + ") OSM Details JSON - " + osm_details_json_input) + #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) + self._osm_details_dict = osm_details_dict + + #Make this work + wikidata_id = "Q178114" + self._wikidata_id = wikidata_id + + wikidata_decoded = {} + if wikidata_id is not None: + wikidata_url = ( + "https://www.wikidata.org/wiki/Special:EntityData/" + + wikidata_id + + ".json" + ) + + _LOGGER.info( + "(" + + self._name + + ") Wikidata request sent with id=" + + wikidata_id + ) + _LOGGER.debug("(" + self._name + ") Wikidata URL - " + wikidata_url) + wikidata_response = get(wikidata_url) + wikidata_json_input = wikidata_response.text + wikidata_dict = json.loads(wikidata_json_input) + _LOGGER.debug("(" + self._name + ") Wikidata JSON - " + wikidata_json_input) + _LOGGER.debug("(" + self._name + ") Wikidata Dict - " + str(wikidata_dict)) + self._wikidata_dict = wikidata_dict _LOGGER.info( "(" @@ -1168,26 +1212,44 @@ def do_update(self, reason): self._state = new_state event_data = {} event_data["entity"] = self._name - event_data["place_name"] = place_name event_data["from_state"] = previous_state event_data["to_state"] = new_state - event_data["distance_from_home"] = distance_from_home - event_data["direction"] = direction - event_data["devicetracker_zone"] = devicetracker_zone - event_data["devicetracker_zone_name"] = devicetracker_zone_name - event_data["latitude"] = self._latitude - event_data["longitude"] = self._longitude - event_data["previous_latitude"] = self._latitude_old - event_data["previous_longitude"] = self._longitude_old - event_data["map"] = self._map_link - event_data["mtime"] = current_time - event_data["osm_id"] = osm_id - event_data["osm_type"] = osm_type + + if place_name is not None: + event_data["place_name"] = place_name + if current_time is not None: + event_data["mtime"] = current_time + if distance_from_home is not None: + event_data["distance_from_home"] = distance_from_home + if direction is not None: + event_data["direction"] = direction + if devicetracker_zone is not None: + event_data["devicetracker_zone"] = devicetracker_zone + if devicetracker_zone_name is not None: + event_data["devicetracker_zone_name"] = devicetracker_zone_name + if self._latitude is not None: + event_data["latitude"] = self._latitude + if self._longitude is not None: + event_data["longitude"] = self._longitude + if self._latitude_old is not None: + event_data["previous_latitude"] = self._latitude_old + if self._longitude_old is not None: + event_data["previous_longitude"] = self._longitude_old + if self._map_link is not None: + event_data["map"] = self._map_link + if osm_id is not None: + event_data["osm_id"] = osm_id + if osm_type is not None: + event_data["osm_type"] = osm_type if self._extended_attr: - event_data["wikidata_id"] = wikidata_id - event_data["osm_dict"] = osm_dict - event_data["osm_details_dict"] = osm_details_dict - event_data["wikidata_dict"] = wikidata_dict + if wikidata_id is not None: + event_data["wikidata_id"] = wikidata_id + if osm_decoded is not None: + event_data["osm_dict"] = osm_decoded + if osm_details_dict is not None: + event_data["osm_details_dict"] = osm_details_dict + if wikidata_dict is not None: + event_data["wikidata_dict"] = wikidata_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) From a3406d68cfbc2c7d92a563c1008cdc4faab09ad5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 13:34:58 -0400 Subject: [PATCH 043/329] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7493f652..a6864eb7 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ Key | Type | Required | Description | Default | `map_provider` | `string` | `False` | `google` or `apple` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` `language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s). | *Refer to Notes +`extended_attr` | `boolean` | `False` | Show extended attributes: `wikidata_id, osm_dict, osm_details_dict, wikidata_dict` (if they exist). Provides many additional attributes for advanced logic. Warning, will make the attributes very long! | `False` `options` | `string` | `False` | Display options: `formatted_place (exclusive option), driving (can be used with formatted_place or other options), zone or zone_name, place, place_name, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home` | `zone, place` Sample attributes that can be used in notifications, alerts, automations, etc: From 337c89ce8c6d66a4c2f7da1c0c58a445a2914655 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 14:09:38 -0400 Subject: [PATCH 044/329] Finish Wikidata ID logic --- custom_components/places/sensor.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 28cd6ba4..586970a1 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -860,6 +860,9 @@ def do_update(self, reason): formatted_address = "" target_option = "" formatted_place = "" + osm_id = None + osm_type = None + wikidata_id = None if "place" in self._options: place_type = osm_decoded["type"] @@ -1171,11 +1174,11 @@ def do_update(self, reason): #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) self._osm_details_dict = osm_details_dict - #Make this work - wikidata_id = "Q178114" + if "extratags" in osm_details_dict and "wikidata" in osm_details_dict["extratags"]: + wikidata_id = osm_details_dict["extratags"]["wikidata"] self._wikidata_id = wikidata_id - wikidata_decoded = {} + wikidata_dict = {} if wikidata_id is not None: wikidata_url = ( "https://www.wikidata.org/wiki/Special:EntityData/" From bbef8aa731405e09adac14fc2e8141baa43995d5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 14:38:09 -0400 Subject: [PATCH 045/329] Black Code Formatting --- custom_components/places/sensor.py | 68 +++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 586970a1..8513f03e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -467,7 +467,7 @@ def entity_picture(self): def extra_state_attributes(self): """Return the state attributes.""" return_attr = {} - + if self._street_number is not None: return_attr[ATTR_STREET_NUMBER] = self._street_number if self._street is not None: @@ -548,7 +548,7 @@ def extra_state_attributes(self): return_attr[ATTR_OSM_DETAILS_DICT] = self._osm_details_dict if self._wikidata_dict is not None: return_attr[ATTR_WIKIDATA_DICT] = self._wikidata_dict - #_LOGGER.debug("(" + self._name + ") Extra State Attributes - " + return_attr) + # _LOGGER.debug("(" + self._name + ") Extra State Attributes - " + return_attr) return return_attr def tsc_update(self, tscarg2, tsarg3, tsarg4): @@ -841,7 +841,7 @@ def do_update(self, reason): osm_json_input = osm_response.text _LOGGER.debug("(" + self._name + ") OSM Response - " + osm_json_input) osm_decoded = json.loads(osm_json_input) - #decoded = osm_decoded + # decoded = osm_decoded place_options = self._options.lower() place_type = "-" @@ -1130,22 +1130,22 @@ def do_update(self, reason): + ") New State from DeviceTracker set to: " + new_state ) - + if self._extended_attr: self._osm_dict = osm_decoded current_time = "%02d:%02d" % (now.hour, now.minute) if previous_state != new_state: - + if self._extended_attr: osm_details_dict = {} if osm_id is not None and osm_type is not None: - if osm_type.lower() == 'node': - osm_type_abbr = 'N' - elif osm_type.lower() == 'way': - osm_type_abbr = 'W' - elif osm_type.lower() == 'relation': - osm_type_abbr = 'R' + if osm_type.lower() == "node": + osm_type_abbr = "N" + elif osm_type.lower() == "way": + osm_type_abbr = "W" + elif osm_type.lower() == "relation": + osm_type_abbr = "R" osm_details_url = ( "https://nominatim.openstreetmap.org/details.php?osmtype=" @@ -1153,7 +1153,11 @@ def do_update(self, reason): + "&osmid=" + osm_id + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" - + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") + + ( + "&email=" + self._api_key + if self._api_key != DEFAULT_KEY + else "" + ) ) _LOGGER.info( @@ -1166,15 +1170,25 @@ def do_update(self, reason): + ") and id=" + str(osm_id) ) - _LOGGER.debug("(" + self._name + ") OSM Details URL - " + osm_details_url) + _LOGGER.debug( + "(" + self._name + ") OSM Details URL - " + osm_details_url + ) osm_details_response = get(osm_details_url) osm_details_json_input = osm_details_response.text osm_details_dict = json.loads(osm_details_json_input) - _LOGGER.debug("(" + self._name + ") OSM Details JSON - " + osm_details_json_input) - #_LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) + _LOGGER.debug( + "(" + + self._name + + ") OSM Details JSON - " + + osm_details_json_input + ) + # _LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) self._osm_details_dict = osm_details_dict - - if "extratags" in osm_details_dict and "wikidata" in osm_details_dict["extratags"]: + + if ( + "extratags" in osm_details_dict + and "wikidata" in osm_details_dict["extratags"] + ): wikidata_id = osm_details_dict["extratags"]["wikidata"] self._wikidata_id = wikidata_id @@ -1192,12 +1206,24 @@ def do_update(self, reason): + ") Wikidata request sent with id=" + wikidata_id ) - _LOGGER.debug("(" + self._name + ") Wikidata URL - " + wikidata_url) + _LOGGER.debug( + "(" + self._name + ") Wikidata URL - " + wikidata_url + ) wikidata_response = get(wikidata_url) wikidata_json_input = wikidata_response.text wikidata_dict = json.loads(wikidata_json_input) - _LOGGER.debug("(" + self._name + ") Wikidata JSON - " + wikidata_json_input) - _LOGGER.debug("(" + self._name + ") Wikidata Dict - " + str(wikidata_dict)) + _LOGGER.debug( + "(" + + self._name + + ") Wikidata JSON - " + + wikidata_json_input + ) + _LOGGER.debug( + "(" + + self._name + + ") Wikidata Dict - " + + str(wikidata_dict) + ) self._wikidata_dict = wikidata_dict _LOGGER.info( @@ -1217,7 +1243,7 @@ def do_update(self, reason): event_data["entity"] = self._name event_data["from_state"] = previous_state event_data["to_state"] = new_state - + if place_name is not None: event_data["place_name"] = place_name if current_time is not None: From 0f337838b654249dbb967d010f1ab64bbd5a3bac Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 15:20:38 -0400 Subject: [PATCH 046/329] Fix Formatted Place Logic --- custom_components/places/sensor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8513f03e..2c0990f3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -987,8 +987,6 @@ def do_update(self, reason): .replace("Proposed", "") .replace("Construction", "") .strip() - + " " - + self._place_category.title().strip() ) elif self._place_category != "-": formatted_place_array.append( From d20bd6eab0cbeed1e0a066c9420f27487b5e9a3b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 16:14:33 -0400 Subject: [PATCH 047/329] Update manifest.json --- custom_components/places/manifest.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/custom_components/places/manifest.json b/custom_components/places/manifest.json index 0e35e34a..39914183 100644 --- a/custom_components/places/manifest.json +++ b/custom_components/places/manifest.json @@ -1,9 +1,11 @@ { "domain": "places", "name": "Places", - "version":"1.9", - "documentation": "/~https://github.com/custom_components/places", + "version":"1", + "documentation": "/~https://github.com/Snuffy2/places", + "issue_tracker": "/~https://github.com/Snuffy2/places/issues", "dependencies": ["device_tracker"], - "codeowners": ["@tenly2000","@iantrich"], - "requirements": [] + "codeowners": ["@tenly2000","@iantrich","@Snuffy2"], + "requirements": [], + "iot_class": "cloud_polling" } From 99acf3e4bfe8c5c3ec26275b0d9a62a20bae3e34 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 13 Aug 2022 21:30:35 -0400 Subject: [PATCH 048/329] Update README.md --- README.md | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a6864eb7..586d66b6 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,30 @@ _Component to integrate with OpenStreetMap Reverse Geocode (PLACE)_ ## Installation +### Installation via HACS + +Unless you have a good reason not to, you probably want to install this component via HACS(Home Assistant Community Store) +1. Ensure that [HACS](https://hacs.xyz/) is installed. +1. Navigate to HACS -> Integrations +1. Open the three-dot menu and select 'Custom Repositories' +1. Put '/~https://github.com/Snuffy2/places' into the 'Repository' textbox. +1. Select 'Integration' as the category +1. Press 'Add'. +1. Find the Places integration in the HACS integration list and install it +1. Add your configuration +1. Restart Home Assistant. + +### Manual Installation + +You probably do not want to do this! Use the HACS method above unless you have a very good reason why you are installing manually + 1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`). -2. If you do not have a `custom_components` directory (folder) there, you need to create it. -3. In the `custom_components` directory (folder) create a new folder called `places`. -4. Download _all_ the files from the `custom_components/places/` directory (folder) in this repository. -5. Place the files you downloaded in the new directory (folder) you created. -6. Add your configuration -6. Restart Home Assistant +1. If you do not have a `custom_components` directory (folder) there, you need to create it. +1. In the `custom_components` directory (folder) create a new folder called `places`. +1. Download _all_ the files from the `custom_components/places/` directory (folder) in this repository. +1. Place the files you downloaded in the new directory (folder) you created. +1. Add your configuration +1. Restart Home Assistant Using your HA configuration directory (folder) as a starting point you should now also have this: @@ -177,9 +194,10 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat logger: default: warn logs: - custom_components.sensor.places: debug + custom_components.places: debug ``` +## Prior Contributions: * Original Author: [Jim Thompson](/~https://github.com/tenly2000) * Subsequent Author: [Ian Richardson](/~https://github.com/iantrich) @@ -192,7 +210,7 @@ If you want to contribute to this please read the [Contribution guidelines](CONT [places]: /~https://github.com/Snuffy2/places [commits-shield]: https://img.shields.io/github/commit-activity/y/Snuffy2/places?style=for-the-badge [commits]: /~https://github.com/Snuffy2/places/commits/newdev -[hacs]: /~https://github.com/Snuffy2/hacs +[hacs]: /~https://github.com/hacs/integration [hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge [discord]: https://discord.gg/Qa5fW2R [discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge From 0a66a01abc2be499e464dbcb1b70b82fa38d81c5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 13:27:04 -0400 Subject: [PATCH 049/329] Delete changelog.md --- changelog.md | 59 ---------------------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 changelog.md diff --git a/changelog.md b/changelog.md deleted file mode 100644 index 0763514a..00000000 --- a/changelog.md +++ /dev/null @@ -1,59 +0,0 @@ -``` -20180330 - Initial Release - - Event driven and timed updates - - Subscribes to DeviceTracker state update events - - State display options are (default "zone, place"): - "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" - - If state display options are specified in the configuration.yaml file: - - The state display string begins as a null and appends the following in order: - - 'zone' - as defined in the device_tracker entity - - If 'place' is included in the options string, a concatenated string is created with the following attributes - - place_name, - - place_category, - - place_type, - - place_neighbourhood, - - street number, - - street - - If 'street_number' and 'street' are also in the options string, they are ignored - - If 'place' is NOT included: - - If 'street_number' is included in the options string, the 'street number' will be appended to the display string - - If 'street' is included in the options string, the 'street name' will be appended to the display string - - If specified in the options string, the following attributes are also appended in order: - - "city" - - "county" - - "state' - - "postal_code" - - "country" - - "formatted_address" - - If for some reason the option string is null at this point, the following values are concatenated: - - "zone" - - "street" - - "city" - - Whenever the actual 'state' changes, this sensor fires a custom event named 'places_state_update' containing: - - entity - - to_state - - from_state - - place_name - - direction - - distance_from_home - - devicetracker_zone - - latitude - - longitude - - Added Map_link option to generate a Google or Apple Maps link to the users current location -20180509 - Updated to support new option value of "do_not_reorder" to disable the automatic ordered display of any specified options - - If "do_not_reorder" appears anywhere in the list of comma delimited options, the state display will be built - using the order of options as they are specified in the options config value. - ie: options: street, street_number, do_not_reorder, postal_code, city, country - will result in a state comprised of: - , , , , - without the "do_not_reorder" option, it would be: - , , , , - - The following attributes can be specified in any order for building the display string manually: - - do_not_reorder - - place_type, place_name, place_category, place_neighbourhood, street_number, street, city, - - postal_town, state, region, county, country, postal_code, formatted_address - Notes: All options must be specified in lower case. - State and Region return the same data (so only use one of them). - - Also added 'options' to the attribute list that gets populated by this sensor (to make it easier to see why a specific state is being generated) -20180510 - Fixed stupid bug introduced yesterday. Converted display options from string to list. -``` From 2d058bd3eb9fc188bf3696b37a3fe8d1d7bf5e1d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 13:29:07 -0400 Subject: [PATCH 050/329] Create hacs.json --- hacs.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 hacs.json diff --git a/hacs.json b/hacs.json new file mode 100644 index 00000000..4d066d1c --- /dev/null +++ b/hacs.json @@ -0,0 +1,5 @@ +{ + "name": "Places", + "render_readme": true, + "hide_default_branch": true +} From b96e999264f3a8fea737d4b562c0d7f11012d473 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 13:18:21 -0400 Subject: [PATCH 051/329] Add HACS Actions --- .github/workflows/black-action.yml | 25 +++++++++++++++++++++++++ .github/workflows/hacs_action.yml | 14 ++++++++++++++ .github/workflows/hassfest.yml | 10 ++++++++++ .github/workflows/my_python_linter.yml | 21 --------------------- 4 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/black-action.yml create mode 100644 .github/workflows/hacs_action.yml create mode 100644 .github/workflows/hassfest.yml delete mode 100644 .github/workflows/my_python_linter.yml diff --git a/.github/workflows/black-action.yml b/.github/workflows/black-action.yml new file mode 100644 index 00000000..979bb592 --- /dev/null +++ b/.github/workflows/black-action.yml @@ -0,0 +1,25 @@ +name: Black Code Formatter +on: [workflow_dispatch, pull_request] +jobs: + linter_name: + name: Black Code Formatter + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Check files using the Black Code Formatter + uses: rickstaa/action-black@v1 + id: action_black + with: + black_args: "." + - name: Create Pull Request + if: steps.action_black.outputs.is_formatted == 'true' + uses: peter-evans/create-pull-request@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + title: "Format Python code with Black Code Formatter" + commit-message: ":art: Format Python code with Black Code Formatter" + body: | + There appear to be some python formatting errors in ${{ github.sha }}. This pull request + uses the [Black Code Formatter](/~https://github.com/psf/black) to fix these issues. + base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch + branch: actions/black diff --git a/.github/workflows/hacs_action.yml b/.github/workflows/hacs_action.yml new file mode 100644 index 00000000..22dc4571 --- /dev/null +++ b/.github/workflows/hacs_action.yml @@ -0,0 +1,14 @@ +name: HACS Action + +on: [workflow_dispatch, pull_request] + +jobs: + hacs: + name: HACS Action + runs-on: "ubuntu-latest" + steps: + - name: HACS Action + uses: "hacs/action@main" + with: + category: "integration" + ignore: "brands" diff --git a/.github/workflows/hassfest.yml b/.github/workflows/hassfest.yml new file mode 100644 index 00000000..7c1561d7 --- /dev/null +++ b/.github/workflows/hassfest.yml @@ -0,0 +1,10 @@ +name: Validate with hassfest + +on: [workflow_dispatch, pull_request] + +jobs: + validate: + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v2" + - uses: "home-assistant/actions/hassfest@master" diff --git a/.github/workflows/my_python_linter.yml b/.github/workflows/my_python_linter.yml deleted file mode 100644 index 9d07f421..00000000 --- a/.github/workflows/my_python_linter.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: My Python Linter (autoflake, isort, black) - -on: [workflow_dispatch, pull_request] - -jobs: - python_linter: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - #- name: Black Code Formatter - # uses: lgeiger/black-action@master - # with: - # args: ". --diff --color --check" - - uses: sailingpalmtree/lint@latest - with: - github_token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }} - # Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review]. - reporter: github-pr-review - # Change reporter level if you need. - # GitHub Status Check won't become failure with warning. - level: warning From 46693a00e9e76fdf460eda97205e41cdd58de9ce Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 15:09:34 -0400 Subject: [PATCH 052/329] Update sensor.py Revert "Update sensor.py" This reverts commit e8b8c9ef1d8e4f96150252e38b3dc92c238c3e03. From 320062051cde37b481f4fc62f5e8c8805ecd3fd1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 20:32:17 -0400 Subject: [PATCH 053/329] Fix Formatted Places Logic Only show Neighborhood if Place Type is Home and move it after the Street. --- custom_components/places/sensor.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 2c0990f3..e0855473 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -974,10 +974,6 @@ def do_update(self, reason): formatted_place_array.append("Driving") isDriving = True if self._place_name == "-": - if self._place_neighbourhood != "-": - formatted_place_array.append( - self._place_neighbourhood.strip() + " Neighborhood" - ) elif ( self._place_type != "-" and self._place_type.lower() != "unclassified" @@ -999,6 +995,8 @@ def do_update(self, reason): formatted_place_array.append( self._street_number.strip() + " " + self._street.strip() ) + if self._place_type != "-" and self._place_neighbourhood != "-": + formatted_place_array.append(self._place_neighbourhood.strip() + " Neighborhood") else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From 2ef2e7a58c30236aa051e3dba6dcee14712332c0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 20:39:40 -0400 Subject: [PATCH 054/329] Update sensor.py --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e0855473..fca713f5 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -974,7 +974,7 @@ def do_update(self, reason): formatted_place_array.append("Driving") isDriving = True if self._place_name == "-": - elif ( + if ( self._place_type != "-" and self._place_type.lower() != "unclassified" ): From 9d2646afcd583759d46e4388e4c5bd3138d59863 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 15 Aug 2022 00:40:09 +0000 Subject: [PATCH 055/329] :art: Format Python code with Black Code Formatter --- custom_components/places/sensor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index fca713f5..4004c6ba 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -996,7 +996,9 @@ def do_update(self, reason): self._street_number.strip() + " " + self._street.strip() ) if self._place_type != "-" and self._place_neighbourhood != "-": - formatted_place_array.append(self._place_neighbourhood.strip() + " Neighborhood") + formatted_place_array.append( + self._place_neighbourhood.strip() + " Neighborhood" + ) else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From c4428a1f5e89f01b6fc28f45f4099e5b691a2372 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 20:47:27 -0400 Subject: [PATCH 056/329] Update black-action.yml --- .github/workflows/black-action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/black-action.yml b/.github/workflows/black-action.yml index 979bb592..f197d0a6 100644 --- a/.github/workflows/black-action.yml +++ b/.github/workflows/black-action.yml @@ -11,6 +11,7 @@ jobs: id: action_black with: black_args: "." + fail_on_error: true - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' uses: peter-evans/create-pull-request@v3 From 5c7313a4bacebbe72cd30e63a8360e5a4ca0b1dd Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 20:48:21 -0400 Subject: [PATCH 057/329] Update sensor.py --- custom_components/places/sensor.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 4004c6ba..fca713f5 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -996,9 +996,7 @@ def do_update(self, reason): self._street_number.strip() + " " + self._street.strip() ) if self._place_type != "-" and self._place_neighbourhood != "-": - formatted_place_array.append( - self._place_neighbourhood.strip() + " Neighborhood" - ) + formatted_place_array.append(self._place_neighbourhood.strip() + " Neighborhood") else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From ee8b5f332f2341d516e46cbe1521e3b21a1f90ff Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 20:50:46 -0400 Subject: [PATCH 058/329] Update black-action.yml --- .github/workflows/black-action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/black-action.yml b/.github/workflows/black-action.yml index f197d0a6..bad1a832 100644 --- a/.github/workflows/black-action.yml +++ b/.github/workflows/black-action.yml @@ -11,7 +11,7 @@ jobs: id: action_black with: black_args: "." - fail_on_error: true + fail_on_error: 'true' - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' uses: peter-evans/create-pull-request@v3 From 763dc9aeadc45a7927f85a9353e1d14760c05456 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 20:52:06 -0400 Subject: [PATCH 059/329] Update sensor.py --- custom_components/places/sensor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index fca713f5..bfc80c37 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -997,6 +997,8 @@ def do_update(self, reason): ) if self._place_type != "-" and self._place_neighbourhood != "-": formatted_place_array.append(self._place_neighbourhood.strip() + " Neighborhood") + + else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From 619767af385f072eb6253aaca8df170e7c40f131 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 15 Aug 2022 00:52:40 +0000 Subject: [PATCH 060/329] :art: Format Python code with Black Code Formatter --- custom_components/places/sensor.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index bfc80c37..eef171b3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -996,8 +996,9 @@ def do_update(self, reason): self._street_number.strip() + " " + self._street.strip() ) if self._place_type != "-" and self._place_neighbourhood != "-": - formatted_place_array.append(self._place_neighbourhood.strip() + " Neighborhood") - + formatted_place_array.append( + self._place_neighbourhood.strip() + " Neighborhood" + ) else: formatted_place_array.append(self._place_name.strip()) From 8d1beb2d7966a842b81adf6fa281d4429d7712c0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 21:02:02 -0400 Subject: [PATCH 061/329] Update sensor.py --- custom_components/places/sensor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index bfc80c37..22a0b534 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -999,6 +999,8 @@ def do_update(self, reason): formatted_place_array.append(self._place_neighbourhood.strip() + " Neighborhood") + + else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From aef7404830698f0279b568616020ef48daae2af8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 15 Aug 2022 01:03:56 +0000 Subject: [PATCH 062/329] :art: Format Python code with Black Code Formatter --- custom_components/places/sensor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 73a84c10..eef171b3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1000,8 +1000,6 @@ def do_update(self, reason): self._place_neighbourhood.strip() + " Neighborhood" ) - - else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From 683e6378c3f58c3f125f1067050e35bc6730074a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 21:27:12 -0400 Subject: [PATCH 063/329] Update and rename black-action.yml to black_automerge.yml --- .../{black-action.yml => black_automerge.yml} | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) rename .github/workflows/{black-action.yml => black_automerge.yml} (63%) diff --git a/.github/workflows/black-action.yml b/.github/workflows/black_automerge.yml similarity index 63% rename from .github/workflows/black-action.yml rename to .github/workflows/black_automerge.yml index bad1a832..e9304a29 100644 --- a/.github/workflows/black-action.yml +++ b/.github/workflows/black_automerge.yml @@ -1,8 +1,8 @@ -name: Black Code Formatter +name: Black Code Formatter Automerge on: [workflow_dispatch, pull_request] jobs: linter_name: - name: Black Code Formatter + name: Black Code Formatter Automerge runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -14,13 +14,22 @@ jobs: fail_on_error: 'true' - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' - uses: peter-evans/create-pull-request@v3 + id: cpr + uses: peter-evans/create-pull-request@v4 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.CPR }} title: "Format Python code with Black Code Formatter" commit-message: ":art: Format Python code with Black Code Formatter" body: | There appear to be some python formatting errors in ${{ github.sha }}. This pull request uses the [Black Code Formatter](/~https://github.com/psf/black) to fix these issues. base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch + delete-branch: true branch: actions/black + - name: Enable Pull Request Automerge + if: steps.cpr.outputs.pull-request-operation == 'created' + uses: peter-evans/enable-pull-request-automerge@v2 + with: + token: ${{ secrets.CPR }} + pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} + merge-method: merge From d6885a177a25c47c0b3c3e3f03a53583ed493336 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 21:34:24 -0400 Subject: [PATCH 064/329] Fix Formatted Places Logic (#28) * Fix Formatted Places Logic Only show Neighborhood if Place Type is Home and move it after the Street. * Update sensor.py * :art: Format Python code with Black Code Formatter * Update sensor.py * Update sensor.py * :art: Format Python code with Black Code Formatter * Update sensor.py * :art: Format Python code with Black Code Formatter --- custom_components/places/sensor.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 2c0990f3..eef171b3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -974,11 +974,7 @@ def do_update(self, reason): formatted_place_array.append("Driving") isDriving = True if self._place_name == "-": - if self._place_neighbourhood != "-": - formatted_place_array.append( - self._place_neighbourhood.strip() + " Neighborhood" - ) - elif ( + if ( self._place_type != "-" and self._place_type.lower() != "unclassified" ): @@ -999,6 +995,11 @@ def do_update(self, reason): formatted_place_array.append( self._street_number.strip() + " " + self._street.strip() ) + if self._place_type != "-" and self._place_neighbourhood != "-": + formatted_place_array.append( + self._place_neighbourhood.strip() + " Neighborhood" + ) + else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From f4f1928267ccbe24307a989b6852d5cdf8244d8a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 13:18:21 -0400 Subject: [PATCH 065/329] Add HACS Actions --- .github/workflows/black_automerge.yml | 35 ++++++++++++++++++++++++++ .github/workflows/hacs_action.yml | 14 +++++++++++ .github/workflows/hassfest.yml | 10 ++++++++ .github/workflows/my_python_linter.yml | 21 ---------------- 4 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/black_automerge.yml create mode 100644 .github/workflows/hacs_action.yml create mode 100644 .github/workflows/hassfest.yml delete mode 100644 .github/workflows/my_python_linter.yml diff --git a/.github/workflows/black_automerge.yml b/.github/workflows/black_automerge.yml new file mode 100644 index 00000000..e9304a29 --- /dev/null +++ b/.github/workflows/black_automerge.yml @@ -0,0 +1,35 @@ +name: Black Code Formatter Automerge +on: [workflow_dispatch, pull_request] +jobs: + linter_name: + name: Black Code Formatter Automerge + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Check files using the Black Code Formatter + uses: rickstaa/action-black@v1 + id: action_black + with: + black_args: "." + fail_on_error: 'true' + - name: Create Pull Request + if: steps.action_black.outputs.is_formatted == 'true' + id: cpr + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.CPR }} + title: "Format Python code with Black Code Formatter" + commit-message: ":art: Format Python code with Black Code Formatter" + body: | + There appear to be some python formatting errors in ${{ github.sha }}. This pull request + uses the [Black Code Formatter](/~https://github.com/psf/black) to fix these issues. + base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch + delete-branch: true + branch: actions/black + - name: Enable Pull Request Automerge + if: steps.cpr.outputs.pull-request-operation == 'created' + uses: peter-evans/enable-pull-request-automerge@v2 + with: + token: ${{ secrets.CPR }} + pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} + merge-method: merge diff --git a/.github/workflows/hacs_action.yml b/.github/workflows/hacs_action.yml new file mode 100644 index 00000000..22dc4571 --- /dev/null +++ b/.github/workflows/hacs_action.yml @@ -0,0 +1,14 @@ +name: HACS Action + +on: [workflow_dispatch, pull_request] + +jobs: + hacs: + name: HACS Action + runs-on: "ubuntu-latest" + steps: + - name: HACS Action + uses: "hacs/action@main" + with: + category: "integration" + ignore: "brands" diff --git a/.github/workflows/hassfest.yml b/.github/workflows/hassfest.yml new file mode 100644 index 00000000..7c1561d7 --- /dev/null +++ b/.github/workflows/hassfest.yml @@ -0,0 +1,10 @@ +name: Validate with hassfest + +on: [workflow_dispatch, pull_request] + +jobs: + validate: + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v2" + - uses: "home-assistant/actions/hassfest@master" diff --git a/.github/workflows/my_python_linter.yml b/.github/workflows/my_python_linter.yml deleted file mode 100644 index 9d07f421..00000000 --- a/.github/workflows/my_python_linter.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: My Python Linter (autoflake, isort, black) - -on: [workflow_dispatch, pull_request] - -jobs: - python_linter: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - #- name: Black Code Formatter - # uses: lgeiger/black-action@master - # with: - # args: ". --diff --color --check" - - uses: sailingpalmtree/lint@latest - with: - github_token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }} - # Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review]. - reporter: github-pr-review - # Change reporter level if you need. - # GitHub Status Check won't become failure with warning. - level: warning From 7eae91e47f1e1faafb01934cfb58f52876b1a42e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 21:34:24 -0400 Subject: [PATCH 066/329] Fix Formatted Places Logic (#28) * Fix Formatted Places Logic Only show Neighborhood if Place Type is Home and move it after the Street. * Update sensor.py * :art: Format Python code with Black Code Formatter * Update sensor.py * Update sensor.py * :art: Format Python code with Black Code Formatter * Update sensor.py * :art: Format Python code with Black Code Formatter --- custom_components/places/sensor.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 2c0990f3..eef171b3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -974,11 +974,7 @@ def do_update(self, reason): formatted_place_array.append("Driving") isDriving = True if self._place_name == "-": - if self._place_neighbourhood != "-": - formatted_place_array.append( - self._place_neighbourhood.strip() + " Neighborhood" - ) - elif ( + if ( self._place_type != "-" and self._place_type.lower() != "unclassified" ): @@ -999,6 +995,11 @@ def do_update(self, reason): formatted_place_array.append( self._street_number.strip() + " " + self._street.strip() ) + if self._place_type != "-" and self._place_neighbourhood != "-": + formatted_place_array.append( + self._place_neighbourhood.strip() + " Neighborhood" + ) + else: formatted_place_array.append(self._place_name.strip()) if self._city != "-": From 9a442a7d21881479f03f34c01b51dbf02fd98209 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 22:06:32 -0400 Subject: [PATCH 067/329] Update black_automerge.yml --- .github/workflows/black_automerge.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/black_automerge.yml b/.github/workflows/black_automerge.yml index e9304a29..98f1ae3e 100644 --- a/.github/workflows/black_automerge.yml +++ b/.github/workflows/black_automerge.yml @@ -26,6 +26,13 @@ jobs: base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true branch: actions/black + - name: Auto approve + if: steps.cpr.outputs.pull-request-operation == 'created' + uses: juliangruber/approve-pull-request-action@v1 + with: + github-token: ${{ secrets.CPR }} + number: ${{ steps.cpr.outputs.pull-request-number }} + - name: Enable Pull Request Automerge if: steps.cpr.outputs.pull-request-operation == 'created' uses: peter-evans/enable-pull-request-automerge@v2 From 8b165c9b95bb248079fb49000f5208b63a32f16d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 22:07:02 -0400 Subject: [PATCH 068/329] Update black_automerge.yml --- .github/workflows/black_automerge.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/black_automerge.yml b/.github/workflows/black_automerge.yml index 98f1ae3e..de33677a 100644 --- a/.github/workflows/black_automerge.yml +++ b/.github/workflows/black_automerge.yml @@ -32,7 +32,6 @@ jobs: with: github-token: ${{ secrets.CPR }} number: ${{ steps.cpr.outputs.pull-request-number }} - - name: Enable Pull Request Automerge if: steps.cpr.outputs.pull-request-operation == 'created' uses: peter-evans/enable-pull-request-automerge@v2 From 69b51952c9506ddc8b1325915c5f8e50890cf6c8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 22:17:48 -0400 Subject: [PATCH 069/329] Update black_automerge.yml --- .github/workflows/black_automerge.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/black_automerge.yml b/.github/workflows/black_automerge.yml index de33677a..89c35e65 100644 --- a/.github/workflows/black_automerge.yml +++ b/.github/workflows/black_automerge.yml @@ -26,16 +26,11 @@ jobs: base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true branch: actions/black - - name: Auto approve + - name: Merge Pull Request if: steps.cpr.outputs.pull-request-operation == 'created' - uses: juliangruber/approve-pull-request-action@v1 + uses: juliangruber/merge-pull-request-action@v1 with: github-token: ${{ secrets.CPR }} number: ${{ steps.cpr.outputs.pull-request-number }} - - name: Enable Pull Request Automerge - if: steps.cpr.outputs.pull-request-operation == 'created' - uses: peter-evans/enable-pull-request-automerge@v2 - with: - token: ${{ secrets.CPR }} - pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} - merge-method: merge + method: squash + repo: juliangruber/octokit-action From e263266b13ad8874025877913d8c315796122fd1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 22:26:11 -0400 Subject: [PATCH 070/329] Update and rename black_automerge.yml to black_action.yml --- .../{black_automerge.yml => black_action.yml} | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) rename .github/workflows/{black_automerge.yml => black_action.yml} (71%) diff --git a/.github/workflows/black_automerge.yml b/.github/workflows/black_action.yml similarity index 71% rename from .github/workflows/black_automerge.yml rename to .github/workflows/black_action.yml index 89c35e65..21b3e0f7 100644 --- a/.github/workflows/black_automerge.yml +++ b/.github/workflows/black_action.yml @@ -1,8 +1,8 @@ -name: Black Code Formatter Automerge +name: Black Code Formatter on: [workflow_dispatch, pull_request] jobs: linter_name: - name: Black Code Formatter Automerge + name: Black Code Formatter runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -26,11 +26,3 @@ jobs: base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true branch: actions/black - - name: Merge Pull Request - if: steps.cpr.outputs.pull-request-operation == 'created' - uses: juliangruber/merge-pull-request-action@v1 - with: - github-token: ${{ secrets.CPR }} - number: ${{ steps.cpr.outputs.pull-request-number }} - method: squash - repo: juliangruber/octokit-action From 83d0ee130ea98be76001df451b94ec6647e0f4c3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 14 Aug 2022 22:06:32 -0400 Subject: [PATCH 071/329] Update HACS Actions --- .../{black_automerge.yml => black_action.yml} | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) rename .github/workflows/{black_automerge.yml => black_action.yml} (72%) diff --git a/.github/workflows/black_automerge.yml b/.github/workflows/black_action.yml similarity index 72% rename from .github/workflows/black_automerge.yml rename to .github/workflows/black_action.yml index e9304a29..21b3e0f7 100644 --- a/.github/workflows/black_automerge.yml +++ b/.github/workflows/black_action.yml @@ -1,8 +1,8 @@ -name: Black Code Formatter Automerge +name: Black Code Formatter on: [workflow_dispatch, pull_request] jobs: linter_name: - name: Black Code Formatter Automerge + name: Black Code Formatter runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -26,10 +26,3 @@ jobs: base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true branch: actions/black - - name: Enable Pull Request Automerge - if: steps.cpr.outputs.pull-request-operation == 'created' - uses: peter-evans/enable-pull-request-automerge@v2 - with: - token: ${{ secrets.CPR }} - pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} - merge-method: merge From 861ada9c64d175d0bec440c3f4afa01ffcb26280 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 17 Aug 2022 20:54:52 -0400 Subject: [PATCH 072/329] Change 'City of' and Further Formatted Places Tweaks Change 'City of' prefix to 'City' suffix (ex. City of New York becomes New York City) --- custom_components/places/sensor.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index eef171b3..54f409b2 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -905,6 +905,8 @@ def do_update(self, reason): city = osm_decoded["address"]["municipality"] elif "city_district" in osm_decoded["address"]: city = osm_decoded["address"]["city_district"] + if city.startswith("City of"): + city = city[8:]+" City" if "city_district" in osm_decoded["address"]: postal_town = osm_decoded["address"]["city_district"] @@ -977,6 +979,7 @@ def do_update(self, reason): if ( self._place_type != "-" and self._place_type.lower() != "unclassified" + and self._place_category.lower() != "highway" ): formatted_place_array.append( self._place_type.title() @@ -984,7 +987,10 @@ def do_update(self, reason): .replace("Construction", "") .strip() ) - elif self._place_category != "-": + elif ( + self._place_category != "-" + and self._place_category.lower() != "highway" + ): formatted_place_array.append( self._place_category.title().strip() ) From b276a3ee166ae3832a9a0b7203a4066933e19f0a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 17 Aug 2022 20:57:43 -0400 Subject: [PATCH 073/329] :art: Format Python code with Black Code Formatter (#44) --- custom_components/places/sensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 54f409b2..d53c0dd5 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -906,7 +906,7 @@ def do_update(self, reason): elif "city_district" in osm_decoded["address"]: city = osm_decoded["address"]["city_district"] if city.startswith("City of"): - city = city[8:]+" City" + city = city[8:] + " City" if "city_district" in osm_decoded["address"]: postal_town = osm_decoded["address"]["city_district"] @@ -988,8 +988,8 @@ def do_update(self, reason): .strip() ) elif ( - self._place_category != "-" - and self._place_category.lower() != "highway" + self._place_category != "-" + and self._place_category.lower() != "highway" ): formatted_place_array.append( self._place_category.title().strip() From 09aa8f78f4ca29b98d344f76a9188f63c38a62a3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 18 Aug 2022 09:52:42 -0400 Subject: [PATCH 074/329] Update sensor.py --- custom_components/places/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index eef171b3..dc7283cf 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -995,10 +995,10 @@ def do_update(self, reason): formatted_place_array.append( self._street_number.strip() + " " + self._street.strip() ) - if self._place_type != "-" and self._place_neighbourhood != "-": - formatted_place_array.append( - self._place_neighbourhood.strip() + " Neighborhood" - ) + if self._place_type.lower() == "house" and self._place_neighbourhood != "-": + formatted_place_array.append( + self._place_neighbourhood.strip() + " Neighborhood" + ) else: formatted_place_array.append(self._place_name.strip()) From 109453628f64d1a050e16a3ab2b5810b88715b31 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 18 Aug 2022 09:55:55 -0400 Subject: [PATCH 075/329] :art: Format Python code with Black Code Formatter (#46) --- custom_components/places/sensor.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 797e20d5..92309f85 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1001,7 +1001,10 @@ def do_update(self, reason): formatted_place_array.append( self._street_number.strip() + " " + self._street.strip() ) - if self._place_type.lower() == "house" and self._place_neighbourhood != "-": + if ( + self._place_type.lower() == "house" + and self._place_neighbourhood != "-" + ): formatted_place_array.append( self._place_neighbourhood.strip() + " Neighborhood" ) From f78a36bc7473640c3bbb4610e99950aad1d68ec7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 20 Aug 2022 16:37:37 -0400 Subject: [PATCH 076/329] Improve New State Checking Don't change from zone_name to zone if the same zone Ignore case in new state checking --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 92309f85..e4ac62b8 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1143,7 +1143,7 @@ def do_update(self, reason): self._osm_dict = osm_decoded current_time = "%02d:%02d" % (now.hour, now.minute) - if previous_state != new_state: + if previous_state.lower().strip() != new_state.lower().strip() and previous_state.replace(' ','').lower().strip() != new_state.lower().strip() and previous_state.lower().strip() != devicetracker_zone.lower().strip(): if self._extended_attr: osm_details_dict = {} From 863f0cb39d09024cadff46f5f87626c034600104 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 20 Aug 2022 20:43:15 +0000 Subject: [PATCH 077/329] :art: Format Python code with Black Code Formatter --- custom_components/places/sensor.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e4ac62b8..591276dc 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1143,7 +1143,12 @@ def do_update(self, reason): self._osm_dict = osm_decoded current_time = "%02d:%02d" % (now.hour, now.minute) - if previous_state.lower().strip() != new_state.lower().strip() and previous_state.replace(' ','').lower().strip() != new_state.lower().strip() and previous_state.lower().strip() != devicetracker_zone.lower().strip(): + if ( + previous_state.lower().strip() != new_state.lower().strip() + and previous_state.replace(" ", "").lower().strip() + != new_state.lower().strip() + and previous_state.lower().strip() != devicetracker_zone.lower().strip() + ): if self._extended_attr: osm_details_dict = {} From 4a98d9a295aa69224c200cd627381b45047e076d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 20 Aug 2022 17:32:41 -0400 Subject: [PATCH 078/329] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 586d66b6..ea5035a8 100644 --- a/README.md +++ b/README.md @@ -185,8 +185,7 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat * This component is only useful to those who have device tracking enabled via a mechanism that provides latitude and longitude co-ordinates (such as Owntracks or iCloud). * The OpenStreetMap database is very flexible with regards to tag_names in their database schema. If you come across a set of co-ordinates that do not parse properly, you can enable debug messages to see the actual JSON that is returned from the query. * The OpenStreetMap API requests that you include your valid e-mail address in each API call if you are making a large numbers of requests. They say that this information will be kept confidential and only used to contact you in the event of a problem, see their Usage Policy for more details. -* The map link that gets generated for Google maps has a push pin marking the users location. -* The map link for Apple maps is centered on the users location - but without any marker. +* The map link that gets generated for Google and Apple has a push pin marking the users location. Note that when opening the Apple link on a non-Apple device, it will open in Google Maps. * When no `language` value is given, default language will be location's local language or English. When a comma separated list of languages is provided - the component will attempt to fill each address field in desired languages by order. * Translations are partial in OpenStreetMap database. For each field, if a translation is missing in first requested language it will be resolved with a language following in the provided list, defaulting to local language if no matching translations were found for the list. * To enable detailed logging for this component, add the following to your configuration.yaml file From 7babbfebb06301f402e8645fc8c37d297904adce Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 1 Sep 2022 20:41:45 -0400 Subject: [PATCH 079/329] Remove the word Neighborhood that I added Stop appending Neighborhood to Neighborhoods. It looks better without I now believe. --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 92309f85..3a5daf0e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1006,7 +1006,7 @@ def do_update(self, reason): and self._place_neighbourhood != "-" ): formatted_place_array.append( - self._place_neighbourhood.strip() + " Neighborhood" + self._place_neighbourhood.strip() ) else: From cf463a6e93adc2a663f88086b0f632a54ac6e09e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 1 Sep 2022 20:44:49 -0400 Subject: [PATCH 080/329] :art: Format Python code with Black Code Formatter (#51) --- custom_components/places/sensor.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 3a5daf0e..c7f04995 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1005,9 +1005,7 @@ def do_update(self, reason): self._place_type.lower() == "house" and self._place_neighbourhood != "-" ): - formatted_place_array.append( - self._place_neighbourhood.strip() - ) + formatted_place_array.append(self._place_neighbourhood.strip()) else: formatted_place_array.append(self._place_name.strip()) From 287c1f44493cbbb5c41c74090f4dc85367c33ee8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 1 Sep 2022 21:54:10 -0400 Subject: [PATCH 081/329] Remove old truncate of previous state Removed leftover truncate to remove the last 14 characters that previously was (since XX:YY). I had previously removed the since but missed a couple of things. Clarified some of the Debug logging. --- custom_components/places/sensor.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 77a87f63..c2fe7c9a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -375,7 +375,7 @@ def __init__( self._language = language.lower() self._language.replace(" ", "") self._extended_attr = extended_attr - self._state = "Initializing... (since 99:99)" + self._state = "Initializing..." home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) home_longitude = str(hass.states.get(home_zone).attributes.get("longitude")) @@ -579,7 +579,8 @@ def haversine(self, lon1, lat1, lon2, lat2): def do_update(self, reason): """Get the latest data and updates the states.""" - previous_state = self.state[:-14] + #previous_state = self.state[:-14] + previous_state = self.state distance_traveled = 0 devicetracker_zone = None @@ -1125,7 +1126,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") New State from DeviceTracker set to: " + + ") New State from DeviceTracker Zone Name set to: " + new_state ) else: @@ -1133,7 +1134,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") New State from DeviceTracker set to: " + + ") New State from DeviceTracker Zone set to: " + new_state ) @@ -1142,10 +1143,11 @@ def do_update(self, reason): current_time = "%02d:%02d" % (now.hour, now.minute) if ( - previous_state.lower().strip() != new_state.lower().strip() + (previous_state.lower().strip() != new_state.lower().strip() and previous_state.replace(" ", "").lower().strip() != new_state.lower().strip() - and previous_state.lower().strip() != devicetracker_zone.lower().strip() + and previous_state.lower().strip() != devicetracker_zone.lower().strip()) + or previous_state.strip() == "Initializing..." ): if self._extended_attr: @@ -1240,8 +1242,10 @@ def do_update(self, reason): _LOGGER.info( "(" + self._name - + ") New state built using options: " + + ") New state built using options [" + self._options + + "]: " + + new_state ) _LOGGER.debug( "(" + self._name + ") Building EventData for (" + new_state + ")" From 896891c021cd355fa7621cca7c5be8866cceee0d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 1 Sep 2022 22:35:17 -0400 Subject: [PATCH 082/329] Debugging Updates --- custom_components/places/sensor.py | 128 ++++++++++++----------------- 1 file changed, 52 insertions(+), 76 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index c2fe7c9a..1103abf8 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -422,14 +422,13 @@ def __init__( self._osm_dict = None self._osm_details_dict = None self._wikidata_dict = None - #'https://www.google.com/maps/@' + home_latitude + "," + home_longitude + ',19z' # Check if devicetracker_id was specified correctly _LOGGER.info( "(" + self._name - + ") DeviceTracker Entity ID is " - + devicetracker_id.split(".", 1)[1] + + ") DeviceTracker Entity ID: " + + devicetracker_id ) if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: @@ -444,8 +443,7 @@ def __init__( _LOGGER.info( "(" + self._name - + ") Now subscribed to state change events from " - + self._devicetracker_id + + ") Now subscribed to state change events" ) @property @@ -579,16 +577,15 @@ def haversine(self, lon1, lat1, lon2, lat2): def do_update(self, reason): """Get the latest data and updates the states.""" - #previous_state = self.state[:-14] previous_state = self.state distance_traveled = 0 devicetracker_zone = None _LOGGER.info("(" + self._name + ") Calling update due to " + reason) _LOGGER.info( - "(" + self._name + ") Check if update req'd : " + self._devicetracker_id + "(" + self._name + ") Check if update req'd: " + self._devicetracker_id ) - _LOGGER.debug("(" + self._name + ") Previous State : " + previous_state) + _LOGGER.debug("(" + self._name + ") Previous State: " + previous_state) if ( hasattr(self, "_devicetracker_id") @@ -613,7 +610,6 @@ def do_update(self, reason): previous_location = old_latitude + "," + old_longitude home_location = home_latitude + "," + home_longitude - # maplink_google ='https://www.google.com/maps/@' + current_location+',' + self._map_zoom + 'z' maplink_apple = ( "https://maps.apple.com/maps/?q=" + current_location @@ -659,21 +655,21 @@ def do_update(self, reason): "(" + self._name + ") Previous Location: " + previous_location ) _LOGGER.debug( - "(" + self._name + ") Current Location : " + current_location + "(" + self._name + ") Current Location: " + current_location ) _LOGGER.debug( - "(" + self._name + ") Home Location : " + home_location + "(" + self._name + ") Home Location: " + home_location ) _LOGGER.info( "(" + self._name - + ") Distance from home : (" + + ") Distance from home [" + (self._home_zone).split(".")[1] - + "): " + + "]: " + distance_from_home ) _LOGGER.info( - "(" + self._name + ") Travel Direction :(" + direction + ")" + "(" + self._name + ") Travel Direction: " + direction ) """Update if location has changed.""" @@ -682,7 +678,7 @@ def do_update(self, reason): _LOGGER.info( "(" + self._name - + ") DeviceTracker Zone (before update): " + + ") DeviceTracker Zone: " + devicetracker_zone ) @@ -690,13 +686,6 @@ def do_update(self, reason): self._devicetracker_id ).attributes.get("zone") devicetracker_zone_id = "zone." + devicetracker_zone_id - _LOGGER.debug( - "(" - + self._name - + ") DeviceTracker Zone ID (before update): " - + devicetracker_zone_id - ) - devicetracker_zone_name_state = self.hass.states.get( devicetracker_zone_id ) @@ -709,7 +698,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") DeviceTracker Zone Name (before update): " + + ") DeviceTracker Zone Name: " + devicetracker_zone_name ) @@ -733,7 +722,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Skipping update because co-ordinates are identical" + + ") Skipping update because coordinates are identical" ) proceed_with_update = False elif int(distance_traveled) > 0 and self._updateskipped > 3: @@ -749,7 +738,7 @@ def do_update(self, reason): "(" + self._name + ") Skipping update because location changed " - + str(distance_traveled) + + str(round(distance_traveled)) + " < 10m (" + str(self._updateskipped) + ")" @@ -758,7 +747,7 @@ def do_update(self, reason): if previous_state == "Initializing...": _LOGGER.debug( - "(" + self._name + ") Peforming Initial Update for user at home..." + "(" + self._name + ") Performing Initial Update for user..." ) proceed_with_update = True @@ -766,16 +755,15 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Proceeding with update for " - + self._devicetracker_id + + ") Meets criteria, proceeding with update" ) self._devicetracker_zone = devicetracker_zone _LOGGER.info( "(" + self._name - + ") DeviceTracker Zone (current) " + + ") DeviceTracker Zone (current): " + self._devicetracker_zone - + " Skipped Updates: " + + " / Skipped Updates: " + str(self._updateskipped) ) @@ -794,24 +782,15 @@ def do_update(self, reason): self._direction = direction if self._map_provider == "google": - _LOGGER.debug( - "(" - + self._name - + ") Google Map Link requested for: [" - + self._map_provider - + "]" - ) self._map_link = maplink_google else: - _LOGGER.debug( - "(" - + self._name - + ") Apple Map Link requested for: [" - + self._map_provider - + "]" - ) self._map_link = maplink_apple - + _LOGGER.debug( + "(" + + self._name + + ") Map Link Type: " + + self._map_provider + ) _LOGGER.debug("(" + self._name + ") Map Link generated: " + self._map_link) osm_url = ( @@ -832,17 +811,16 @@ def do_update(self, reason): _LOGGER.info( "(" + self._name - + ") OpenStreetMap request sent with lat=" + + ") OpenStreetMap Request: lat=" + self._latitude + " and lon=" + self._longitude ) - _LOGGER.debug("(" + self._name + ") OSM URL - " + osm_url) + _LOGGER.debug("(" + self._name + ") OSM URL: " + osm_url) osm_response = get(osm_url) osm_json_input = osm_response.text - _LOGGER.debug("(" + self._name + ") OSM Response - " + osm_json_input) + _LOGGER.debug("(" + self._name + ") OSM Response: " + osm_json_input) osm_decoded = json.loads(osm_json_input) - # decoded = osm_decoded place_options = self._options.lower() place_type = "-" @@ -1033,6 +1011,12 @@ def do_update(self, reason): ) elif "formatted_place" in display_options: new_state = self._formatted_place + _LOGGER.info( + "(" + + self._name + + ") New State using formatted_place: " + + new_state + ) elif ( self._devicetracker_zone.lower() == "not_home" or "stationary" in self._devicetracker_zone.lower() @@ -1118,7 +1102,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") New State built from Display Options will be: " + + ") New State from Display Options: " + new_state ) elif "zone_name" in display_options: @@ -1126,7 +1110,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") New State from DeviceTracker Zone Name set to: " + + ") New State from DeviceTracker Zone Name: " + new_state ) else: @@ -1134,7 +1118,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") New State from DeviceTracker Zone set to: " + + ") New State from DeviceTracker Zone: " + new_state ) @@ -1176,7 +1160,7 @@ def do_update(self, reason): _LOGGER.info( "(" + self._name - + ") OpenStreetMap Details request sent with type=" + + ") OpenStreetMap Details Request: type=" + osm_type + " (" + osm_type_abbr @@ -1184,7 +1168,7 @@ def do_update(self, reason): + str(osm_id) ) _LOGGER.debug( - "(" + self._name + ") OSM Details URL - " + osm_details_url + "(" + self._name + ") OSM Details URL: " + osm_details_url ) osm_details_response = get(osm_details_url) osm_details_json_input = osm_details_response.text @@ -1192,10 +1176,10 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") OSM Details JSON - " + + ") OSM Details JSON: " + osm_details_json_input ) - # _LOGGER.debug("(" + self._name + ") OSM Details Dict - " + str(osm_details_dict)) + # _LOGGER.debug("(" + self._name + ") OSM Details Dict: " + str(osm_details_dict)) self._osm_details_dict = osm_details_dict if ( @@ -1216,11 +1200,11 @@ def do_update(self, reason): _LOGGER.info( "(" + self._name - + ") Wikidata request sent with id=" + + ") Wikidata Request: id=" + wikidata_id ) _LOGGER.debug( - "(" + self._name + ") Wikidata URL - " + wikidata_url + "(" + self._name + ") Wikidata URL: " + wikidata_url ) wikidata_response = get(wikidata_url) wikidata_json_input = wikidata_response.text @@ -1228,30 +1212,18 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Wikidata JSON - " + + ") Wikidata JSON: " + wikidata_json_input ) _LOGGER.debug( "(" + self._name - + ") Wikidata Dict - " + + ") Wikidata Dict: " + str(wikidata_dict) ) self._wikidata_dict = wikidata_dict - - _LOGGER.info( - "(" - + self._name - + ") New state built using options [" - + self._options - + "]: " - + new_state - ) _LOGGER.debug( - "(" + self._name + ") Building EventData for (" + new_state + ")" - ) - # new_state = new_state[:(255-14)] - # self._state = new_state + " (since " + current_time + ")" + "(" + self._name + ") Building EventData" ) new_state = new_state[:255] self._state = new_state event_data = {} @@ -1295,10 +1267,14 @@ def do_update(self, reason): if wikidata_dict is not None: event_data["wikidata_dict"] = wikidata_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) - # self._hass.bus.fire(DEFAULT_NAME+'_state_update', { 'entity': self._name, 'place_name': place_name, 'from_state': previous_state, 'to_state': new_state, 'distance_from_home': distance_from_home, 'direction': direction, 'devicetracker_zone': devicetracker_zone, 'mtime': current_time, 'latitude': self._latitude, 'longitude': self._longitude, 'map': self._map_link }) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) - _LOGGER.debug("(" + self._name + ") Update complete...") - + _LOGGER.debug("(" + self._name + ") EventData update complete") + else: + _LOGGER.debug( + "(" + + self._name + + ") No update needed, Previous State = New State" + ) def _reset_attributes(self): """Resets attributes.""" self._street = None From b443680d61d1580240b21f04b45ad26a1b2db626 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 1 Sep 2022 23:28:11 -0400 Subject: [PATCH 083/329] :art: Format Python code with Black Code Formatter (#53) --- custom_components/places/sensor.py | 70 ++++++++---------------------- 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 1103abf8..4ca347bd 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -425,10 +425,7 @@ def __init__( # Check if devicetracker_id was specified correctly _LOGGER.info( - "(" - + self._name - + ") DeviceTracker Entity ID: " - + devicetracker_id + "(" + self._name + ") DeviceTracker Entity ID: " + devicetracker_id ) if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: @@ -440,11 +437,7 @@ def __init__( from_state=None, to_state=None, ) - _LOGGER.info( - "(" - + self._name - + ") Now subscribed to state change events" - ) + _LOGGER.info("(" + self._name + ") Now subscribed to state change events") @property def name(self): @@ -657,9 +650,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name + ") Current Location: " + current_location ) - _LOGGER.debug( - "(" + self._name + ") Home Location: " + home_location - ) + _LOGGER.debug("(" + self._name + ") Home Location: " + home_location) _LOGGER.info( "(" + self._name @@ -668,18 +659,13 @@ def do_update(self, reason): + "]: " + distance_from_home ) - _LOGGER.info( - "(" + self._name + ") Travel Direction: " + direction - ) + _LOGGER.info("(" + self._name + ") Travel Direction: " + direction) """Update if location has changed.""" devicetracker_zone = self.hass.states.get(self._devicetracker_id).state _LOGGER.info( - "(" - + self._name - + ") DeviceTracker Zone: " - + devicetracker_zone + "(" + self._name + ") DeviceTracker Zone: " + devicetracker_zone ) devicetracker_zone_id = self.hass.states.get( @@ -720,9 +706,7 @@ def do_update(self, reason): if current_location == previous_location: _LOGGER.debug( - "(" - + self._name - + ") Skipping update because coordinates are identical" + "(" + self._name + ") Skipping update because coordinates are identical" ) proceed_with_update = False elif int(distance_traveled) > 0 and self._updateskipped > 3: @@ -746,17 +730,11 @@ def do_update(self, reason): proceed_with_update = False if previous_state == "Initializing...": - _LOGGER.debug( - "(" + self._name + ") Performing Initial Update for user..." - ) + _LOGGER.debug("(" + self._name + ") Performing Initial Update for user...") proceed_with_update = True if proceed_with_update and devicetracker_zone: - _LOGGER.debug( - "(" - + self._name - + ") Meets criteria, proceeding with update" - ) + _LOGGER.debug("(" + self._name + ") Meets criteria, proceeding with update") self._devicetracker_zone = devicetracker_zone _LOGGER.info( "(" @@ -785,12 +763,7 @@ def do_update(self, reason): self._map_link = maplink_google else: self._map_link = maplink_apple - _LOGGER.debug( - "(" - + self._name - + ") Map Link Type: " - + self._map_provider - ) + _LOGGER.debug("(" + self._name + ") Map Link Type: " + self._map_provider) _LOGGER.debug("(" + self._name + ") Map Link generated: " + self._map_link) osm_url = ( @@ -1012,10 +985,7 @@ def do_update(self, reason): elif "formatted_place" in display_options: new_state = self._formatted_place _LOGGER.info( - "(" - + self._name - + ") New State using formatted_place: " - + new_state + "(" + self._name + ") New State using formatted_place: " + new_state ) elif ( self._devicetracker_zone.lower() == "not_home" @@ -1100,10 +1070,7 @@ def do_update(self, reason): new_state = ", ".join(item for item in user_display) _LOGGER.debug( - "(" - + self._name - + ") New State from Display Options: " - + new_state + "(" + self._name + ") New State from Display Options: " + new_state ) elif "zone_name" in display_options: new_state = devicetracker_zone_name @@ -1127,12 +1094,11 @@ def do_update(self, reason): current_time = "%02d:%02d" % (now.hour, now.minute) if ( - (previous_state.lower().strip() != new_state.lower().strip() + previous_state.lower().strip() != new_state.lower().strip() and previous_state.replace(" ", "").lower().strip() != new_state.lower().strip() - and previous_state.lower().strip() != devicetracker_zone.lower().strip()) - or previous_state.strip() == "Initializing..." - ): + and previous_state.lower().strip() != devicetracker_zone.lower().strip() + ) or previous_state.strip() == "Initializing...": if self._extended_attr: osm_details_dict = {} @@ -1222,8 +1188,7 @@ def do_update(self, reason): + str(wikidata_dict) ) self._wikidata_dict = wikidata_dict - _LOGGER.debug( - "(" + self._name + ") Building EventData" ) + _LOGGER.debug("(" + self._name + ") Building EventData") new_state = new_state[:255] self._state = new_state event_data = {} @@ -1271,10 +1236,9 @@ def do_update(self, reason): _LOGGER.debug("(" + self._name + ") EventData update complete") else: _LOGGER.debug( - "(" - + self._name - + ") No update needed, Previous State = New State" + "(" + self._name + ") No update needed, Previous State = New State" ) + def _reset_attributes(self): """Resets attributes.""" self._street = None From c07935404e5978574a7d02f5f9506c5cdf2ce92a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 19:35:59 -0400 Subject: [PATCH 084/329] Update CONTRIBUTING.md --- CONTRIBUTING.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e91c221a..18fb4f8b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,9 +18,9 @@ Pull requests are the best way to propose changes to the codebase. 3. Make sure your code lints (using black). 4. Issue that pull request! -## Any contributions you make will be under the MIT Software License +## Any contributions you make will be under the GPL-3.0 Software License -In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. +In short, when you submit code changes, your submissions are understood to be under the same [License](../../blob/newdev/LICENSE) that covers the project. Feel free to contact the maintainers if that's a concern. ## Report bugs using Github's [issues](../../issues) @@ -35,16 +35,29 @@ Report a bug by [opening a new issue](../../issues/new/choose); it's that easy! - Steps to reproduce - Be specific! - Give sample code if you can. +- Show logs + - Ideally enable debug logging in Home Assistant - What you expected would happen - What actually happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) People *love* thorough bug reports. I'm not even kidding. + +**Enable debug logging in Home Assistant** + +To enable, add this or modify the logging section of your Home Assistant configuration.yaml: +``` +logger: + default: warning + logs: + custom_components.places: debug +``` + ## Use a Consistent Coding Style Use [black](/~https://github.com/ambv/black) to make sure the code follows the style. ## License -By contributing, you agree that your contributions will be licensed under its MIT License. +By contributing, you agree that your contributions will be licensed under its GPL-3.0 License. From 64bb161354f184d46cab061221d1267cdd18a2ae Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 19:37:15 -0400 Subject: [PATCH 085/329] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ea5035a8..e66a0852 100644 --- a/README.md +++ b/README.md @@ -182,8 +182,8 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat ## Notes: -* This component is only useful to those who have device tracking enabled via a mechanism that provides latitude and longitude co-ordinates (such as Owntracks or iCloud). -* The OpenStreetMap database is very flexible with regards to tag_names in their database schema. If you come across a set of co-ordinates that do not parse properly, you can enable debug messages to see the actual JSON that is returned from the query. +* This component is only useful to those who have device tracking enabled via a mechanism that provides latitude and longitude coordinates (such as Owntracks or iCloud). +* The OpenStreetMap database is very flexible with regards to tag_names in their database schema. If you come across a set of coordinates that do not parse properly, you can enable debug messages to see the actual JSON that is returned from the query. * The OpenStreetMap API requests that you include your valid e-mail address in each API call if you are making a large numbers of requests. They say that this information will be kept confidential and only used to contact you in the event of a problem, see their Usage Policy for more details. * The map link that gets generated for Google and Apple has a push pin marking the users location. Note that when opening the Apple link on a non-Apple device, it will open in Google Maps. * When no `language` value is given, default language will be location's local language or English. When a comma separated list of languages is provided - the component will attempt to fill each address field in desired languages by order. @@ -191,7 +191,7 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat * To enable detailed logging for this component, add the following to your configuration.yaml file ```yaml logger: - default: warn + default: warning logs: custom_components.places: debug ``` From f4a5f749a74b4234a8d9f74929b9f07bff941e98 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 19:38:05 -0400 Subject: [PATCH 086/329] Update CONTRIBUTING.md --- CONTRIBUTING.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18fb4f8b..19f3830b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,11 +43,10 @@ Report a bug by [opening a new issue](../../issues/new/choose); it's that easy! People *love* thorough bug reports. I'm not even kidding. - -**Enable debug logging in Home Assistant** +## Enable debug logging in Home Assistant To enable, add this or modify the logging section of your Home Assistant configuration.yaml: -``` +```yaml logger: default: warning logs: From eae0dde4de09b7d38b7a4324a253d50fc75ac089 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 19:57:42 -0400 Subject: [PATCH 087/329] Fix check for new lat/long problems Was checking for None as a string. Fixed and added Error Logging if any of new lat/long are None. --- custom_components/places/sensor.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 4ca347bd..4ca947cb 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -615,10 +615,10 @@ def do_update(self, reason): + current_location ) if ( - new_latitude != "None" - and new_longitude != "None" - and home_latitude != "None" - and home_longitude != "None" + new_latitude is not None + and new_longitude is not None + and home_latitude is not None + and home_longitude is not None ): distance_m = distance( float(new_latitude), @@ -701,6 +701,19 @@ def do_update(self, reason): + ") Meters traveled since last update: " + str(round(distance_traveled)) ) + else: + _LOGGER.error( + "(" + + self._name + + ") Problem with updated lat/long, this will likely error: new_latitude=" + + new_latitude + + ", new_longitude=" + + new_longitude + + ", home_latitude=" + + home_latitude + + ", home_longitude=" + + home_longitude + ) proceed_with_update = True From c6778bd76e4c35246f0f84edab79f6e177c228d8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 20:04:22 -0400 Subject: [PATCH 088/329] Throw Error if no _devicetracker_id Future improvement to handle more elegantly. --- custom_components/places/sensor.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 4ca947cb..5f50793f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -714,6 +714,12 @@ def do_update(self, reason): + ", home_longitude=" + home_longitude ) + else: + _LOGGER.error( + "(" + + self._name + + ") Missing _devicetracker_id, this will likely error" + ) proceed_with_update = True From 7e03ce26d2d2e782245df4ef2f2481d544c8631e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 20:08:29 -0400 Subject: [PATCH 089/329] Pre-declare Some Variables in Update Should fail a bit more gracefully in some circumstances --- custom_components/places/sensor.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5f50793f..1299eddf 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -573,6 +573,15 @@ def do_update(self, reason): previous_state = self.state distance_traveled = 0 devicetracker_zone = None + home_latitude = None + home_longitude = None + last_distance_m = None + last_updated = None + current_location = None + previous_location = None + home_location = None + maplink_apple = None + maplink_google = None _LOGGER.info("(" + self._name + ") Calling update due to " + reason) _LOGGER.info( From 589a2fa29fe9b63fc1a65eee483e8ad3b5ebad79 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 20:16:25 -0400 Subject: [PATCH 090/329] Improve Error Handling if JSON Get fails Untested, but hopefully works --- custom_components/places/sensor.py | 104 ++++++++++++++++------------- 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 1299eddf..c95888f8 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1008,7 +1008,7 @@ def do_update(self, reason): if "error_message" in osm_decoded: new_state = osm_decoded["error_message"] _LOGGER.info( - "(" + self._name + ") An error occurred contacting the web service" + "(" + self._name + ") An error occurred contacting the web service for OpenStreetMap" ) elif "formatted_place" in display_options: new_state = self._formatted_place @@ -1165,57 +1165,69 @@ def do_update(self, reason): "(" + self._name + ") OSM Details URL: " + osm_details_url ) osm_details_response = get(osm_details_url) - osm_details_json_input = osm_details_response.text - osm_details_dict = json.loads(osm_details_json_input) - _LOGGER.debug( - "(" - + self._name - + ") OSM Details JSON: " - + osm_details_json_input - ) - # _LOGGER.debug("(" + self._name + ") OSM Details Dict: " + str(osm_details_dict)) - self._osm_details_dict = osm_details_dict - - if ( - "extratags" in osm_details_dict - and "wikidata" in osm_details_dict["extratags"] - ): - wikidata_id = osm_details_dict["extratags"]["wikidata"] - self._wikidata_id = wikidata_id - - wikidata_dict = {} - if wikidata_id is not None: - wikidata_url = ( - "https://www.wikidata.org/wiki/Special:EntityData/" - + wikidata_id - + ".json" - ) - + if "error_message" in osm_details_response: + osm_details_dict = osm_details_response["error_message"] _LOGGER.info( - "(" - + self._name - + ") Wikidata Request: id=" - + wikidata_id - ) - _LOGGER.debug( - "(" + self._name + ") Wikidata URL: " + wikidata_url - ) - wikidata_response = get(wikidata_url) - wikidata_json_input = wikidata_response.text - wikidata_dict = json.loads(wikidata_json_input) - _LOGGER.debug( - "(" - + self._name - + ") Wikidata JSON: " - + wikidata_json_input + "(" + self._name + ") An error occurred contacting the web service for OSM Details" ) + else: + osm_details_json_input = osm_details_response.text + osm_details_dict = json.loads(osm_details_json_input) _LOGGER.debug( "(" + self._name - + ") Wikidata Dict: " - + str(wikidata_dict) + + ") OSM Details JSON: " + + osm_details_json_input ) - self._wikidata_dict = wikidata_dict + # _LOGGER.debug("(" + self._name + ") OSM Details Dict: " + str(osm_details_dict)) + self._osm_details_dict = osm_details_dict + + if ( + "extratags" in osm_details_dict + and "wikidata" in osm_details_dict["extratags"] + ): + wikidata_id = osm_details_dict["extratags"]["wikidata"] + self._wikidata_id = wikidata_id + + wikidata_dict = {} + if wikidata_id is not None: + wikidata_url = ( + "https://www.wikidata.org/wiki/Special:EntityData/" + + wikidata_id + + ".json" + ) + + _LOGGER.info( + "(" + + self._name + + ") Wikidata Request: id=" + + wikidata_id + ) + _LOGGER.debug( + "(" + self._name + ") Wikidata URL: " + wikidata_url + ) + wikidata_response = get(wikidata_url) + if "error_message" in wikidata_response: + wikidata_dict = wikidata_response["error_message"] + _LOGGER.info( + "(" + self._name + ") An error occurred contacting the web service for Wikidata" + ) + else: + wikidata_json_input = wikidata_response.text + wikidata_dict = json.loads(wikidata_json_input) + _LOGGER.debug( + "(" + + self._name + + ") Wikidata JSON: " + + wikidata_json_input + ) + _LOGGER.debug( + "(" + + self._name + + ") Wikidata Dict: " + + str(wikidata_dict) + ) + self._wikidata_dict = wikidata_dict _LOGGER.debug("(" + self._name + ") Building EventData") new_state = new_state[:255] self._state = new_state From c5fdfb2b183a88b08066f9796df822e4821c1628 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 21:28:32 -0400 Subject: [PATCH 091/329] Gracefully handle if zone_id is blank Pre-declare the zone id and name variables. Test if they are None before using the, --- custom_components/places/sensor.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index c95888f8..e6c59555 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -573,6 +573,8 @@ def do_update(self, reason): previous_state = self.state distance_traveled = 0 devicetracker_zone = None + devicetracker_zone_id = None + devicetracker_zone_name_state = None home_latitude = None home_longitude = None last_distance_m = None @@ -680,14 +682,13 @@ def do_update(self, reason): devicetracker_zone_id = self.hass.states.get( self._devicetracker_id ).attributes.get("zone") - devicetracker_zone_id = "zone." + devicetracker_zone_id - devicetracker_zone_name_state = self.hass.states.get( - devicetracker_zone_id - ) - if devicetracker_zone_name_state: - devicetracker_zone_name = self.hass.states.get( + if devicetracker_zone_id is not None: + devicetracker_zone_id = "zone." + devicetracker_zone_id + devicetracker_zone_name_state = self.hass.states.get( devicetracker_zone_id - ).name + ) + if devicetracker_zone_name_state is not None: + devicetracker_zone_name = devicetracker_zone_name_state.name else: devicetracker_zone_name = devicetracker_zone _LOGGER.debug( From cee686ce81a80ea457217e6c8a1704df6e4a50ce Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 21:39:30 -0400 Subject: [PATCH 092/329] :art: Format Python code with Black Code Formatter (#56) --- custom_components/places/sensor.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e6c59555..b43d5e6e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -726,9 +726,7 @@ def do_update(self, reason): ) else: _LOGGER.error( - "(" - + self._name - + ") Missing _devicetracker_id, this will likely error" + "(" + self._name + ") Missing _devicetracker_id, this will likely error" ) proceed_with_update = True @@ -1009,7 +1007,9 @@ def do_update(self, reason): if "error_message" in osm_decoded: new_state = osm_decoded["error_message"] _LOGGER.info( - "(" + self._name + ") An error occurred contacting the web service for OpenStreetMap" + "(" + + self._name + + ") An error occurred contacting the web service for OpenStreetMap" ) elif "formatted_place" in display_options: new_state = self._formatted_place @@ -1169,7 +1169,9 @@ def do_update(self, reason): if "error_message" in osm_details_response: osm_details_dict = osm_details_response["error_message"] _LOGGER.info( - "(" + self._name + ") An error occurred contacting the web service for OSM Details" + "(" + + self._name + + ") An error occurred contacting the web service for OSM Details" ) else: osm_details_json_input = osm_details_response.text @@ -1211,7 +1213,9 @@ def do_update(self, reason): if "error_message" in wikidata_response: wikidata_dict = wikidata_response["error_message"] _LOGGER.info( - "(" + self._name + ") An error occurred contacting the web service for Wikidata" + "(" + + self._name + + ") An error occurred contacting the web service for Wikidata" ) else: wikidata_json_input = wikidata_response.text From 219ad524ce0fd3a0029a15ce134178d1bc5b41f8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 21:45:21 -0400 Subject: [PATCH 093/329] Debug Logging Updates --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b43d5e6e..058be732 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -709,7 +709,7 @@ def do_update(self, reason): "(" + self._name + ") Meters traveled since last update: " - + str(round(distance_traveled)) + + str(round(distance_traveled,1)) ) else: _LOGGER.error( @@ -749,7 +749,7 @@ def do_update(self, reason): "(" + self._name + ") Skipping update because location changed " - + str(round(distance_traveled)) + + str(round(distance_traveled,1)) + " < 10m (" + str(self._updateskipped) + ")" From 43dc2946cb3a7b668b35c52196738bc71ed298f3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 22:02:15 -0400 Subject: [PATCH 094/329] :art: Format Python code with Black Code Formatter (#57) --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 058be732..6499b267 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -709,7 +709,7 @@ def do_update(self, reason): "(" + self._name + ") Meters traveled since last update: " - + str(round(distance_traveled,1)) + + str(round(distance_traveled, 1)) ) else: _LOGGER.error( @@ -749,7 +749,7 @@ def do_update(self, reason): "(" + self._name + ") Skipping update because location changed " - + str(round(distance_traveled,1)) + + str(round(distance_traveled, 1)) + " < 10m (" + str(self._updateskipped) + ")" From ac4c5eb170921079bfa4725ba8adeb396f7a4940 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 21:45:21 -0400 Subject: [PATCH 095/329] Debug Logging Updates --- custom_components/places/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b43d5e6e..4541086c 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -709,7 +709,7 @@ def do_update(self, reason): "(" + self._name + ") Meters traveled since last update: " - + str(round(distance_traveled)) + + str(round(distance_traveled,1)) ) else: _LOGGER.error( @@ -749,7 +749,7 @@ def do_update(self, reason): "(" + self._name + ") Skipping update because location changed " - + str(round(distance_traveled)) + + str(round(distance_traveled,1)) + " < 10m (" + str(self._updateskipped) + ")" @@ -761,7 +761,7 @@ def do_update(self, reason): proceed_with_update = True if proceed_with_update and devicetracker_zone: - _LOGGER.debug("(" + self._name + ") Meets criteria, proceeding with update") + _LOGGER.debug("(" + self._name + ") Meets criteria, proceeding with OpenStreetMap query") self._devicetracker_zone = devicetracker_zone _LOGGER.info( "(" @@ -1281,7 +1281,7 @@ def do_update(self, reason): _LOGGER.debug("(" + self._name + ") EventData update complete") else: _LOGGER.debug( - "(" + self._name + ") No update needed, Previous State = New State" + "(" + self._name + ") No entity update needed, Previous State = New State" ) def _reset_attributes(self): From c309e67f653b859a3bb34db505b0b72c053fe452 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 22:15:50 -0400 Subject: [PATCH 096/329] :art: Format Python code with Black Code Formatter (#58) --- custom_components/places/sensor.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 4541086c..47f759fc 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -709,7 +709,7 @@ def do_update(self, reason): "(" + self._name + ") Meters traveled since last update: " - + str(round(distance_traveled,1)) + + str(round(distance_traveled, 1)) ) else: _LOGGER.error( @@ -749,7 +749,7 @@ def do_update(self, reason): "(" + self._name + ") Skipping update because location changed " - + str(round(distance_traveled,1)) + + str(round(distance_traveled, 1)) + " < 10m (" + str(self._updateskipped) + ")" @@ -761,7 +761,11 @@ def do_update(self, reason): proceed_with_update = True if proceed_with_update and devicetracker_zone: - _LOGGER.debug("(" + self._name + ") Meets criteria, proceeding with OpenStreetMap query") + _LOGGER.debug( + "(" + + self._name + + ") Meets criteria, proceeding with OpenStreetMap query" + ) self._devicetracker_zone = devicetracker_zone _LOGGER.info( "(" @@ -1281,7 +1285,9 @@ def do_update(self, reason): _LOGGER.debug("(" + self._name + ") EventData update complete") else: _LOGGER.debug( - "(" + self._name + ") No entity update needed, Previous State = New State" + "(" + + self._name + + ") No entity update needed, Previous State = New State" ) def _reset_attributes(self): From 92404b96f4b46d46f179562626328e37963e8ec8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 2 Sep 2022 22:21:06 -0400 Subject: [PATCH 097/329] Clean up the initial description comments --- custom_components/places/sensor.py | 78 +++--------------------------- 1 file changed, 6 insertions(+), 72 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 47f759fc..ca988960 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -2,76 +2,15 @@ Place Support for OpenStreetMap Geocode sensors. Original Author: Jim Thompson +Subsequent Author: Ian Richardson -Current Version: 1.8 20210125 - iantrich - -20180330 - Initial Release - - Event driven and timed updates - - Subscribes to DeviceTracker state update events - - State display options are (default "zone, place"): - "zone, place, street_number, street, city, county, state, postal_code, country, formatted_address" - - If state display options are specified in the configuration.yaml file: - - The state display string begins as a null and appends the following in order: - - 'zone' - as defined in the device_tracker entity - - If 'place' is included in the options string, a concatenated string is created with the following attributes - - place_name, - - place_category, - - place_type, - - place_neighbourhood, - - street number, - - street - - If 'street_number' and 'street' are also in the options string, they are ignored - - If 'place' is NOT included: - - If 'street_number' is included in the options string, the 'street number' will be appended to the display string - - If 'street' is included in the options string, the 'street name' will be appended to the display string - - If specified in the options string, the following attributes are also appended in order: - - "city" - - "county" - - "state' - - "postal_code" - - "country" - - "formatted_address" - - If for some reason the option string is null at this point, the following values are concatenated: - - "zone" - - "street" - - "city" - - Whenever the actual 'state' changes, this sensor fires a custom event named 'places_state_update' containing: - - entity - - to_state - - from_state - - place_name - - direction - - distance_from_home - - devicetracker_zone - - latitude - - longitude - - Added Map_link option to generate a Google or Apple Maps link to the users current location -20180509 - Updated to support new option value of "do_not_reorder" to disable the automatic ordered display of any specified options - - If "do_not_reorder" appears anywhere in the list of comma delimited options, the state display will be built - using the order of options as they are specified in the options config value. - ie: options: street, street_number, do_not_reorder, postal_code, city, country - will result in a state comprised of: - , , , , - without the "do_not_reorder" option, it would be: - , , , , - - The following attributes can be specified in any order for building the display string manually: - - do_not_reorder - - place_type, place_name, place_category, place_neighbourhood, street_number, street, city, - - postal_town, state, region, county, country, postal_code, formatted_address - Notes: All options must be specified in lower case. - State and Region return the same data (so only use one of them). - - Also added 'options' to the attribute list that gets populated by this sensor (to make it easier to see why a specific state is being generated) -20180510 - Fixed stupid bug introduced yesterday. Converted display options from string to list. - - Description: Provides a sensor with a variable state consisting of reverse geocode (place) details for a linked device_tracker entity that provides GPS co-ordinates (ie owntracks, icloud) Optionally allows you to specify a 'home_zone' for each device and calculates distance from home and direction of travel. - The displayed state adds a time stamp "(since hh:mm)" so you can tell how long a person has been at a location. Configuration Instructions are below - as well as sample automations for notifications. The display options I have set for Sharon are "zone, place" so her state is displayed as: - - not_home, Richmond Hill GO Station, building, building, Beverley Acres, 6, Newkirk Road (since 18:44) + - not_home, Richmond Hill GO Station, building, building, Beverley Acres, 6, Newkirk Road There are a lot of additional attributes (beyond state) that are available which can be used in notifications, alerts, etc: (The "home latitude/longitudes" below have been randomized to protect her privacy) { @@ -188,13 +127,9 @@ hide_thumbnail: false -Note: The OpenStreetMap database is very flexible with regards to tag_names in their - database schema. If you come across a set of co-ordinates that do not parse - properly, you can enable debug messages to see the actual JSON that is returned from the query. +Note: The OpenStreetMap database is very flexible with regards to tag_names in their database schema. If you come across a set of co-ordinates that do not parse properly, you can enable debug messages to see the actual JSON that is returned from the query. -Note: The OpenStreetMap API requests that you include your valid e-mail address in each API call - if you are making a large numbers of requests. They say that this information will be kept - confidential and only used to contact you in the event of a problem, see their Usage Policy for more details. +Note: The OpenStreetMap API requests that you include your valid e-mail address in each API call if you are making a large numbers of requests. They say that this information will be kept confidential and only used to contact you in the event of a problem, see their Usage Policy for more details. Configuration.yaml: sensor places_jim: @@ -207,12 +142,11 @@ map_zoom: <1-20> (optional) option: (optional) -The map link that gets generated for Google maps has a push pin marking the users location. -The map link for Apple maps is centered on the users location - but without any marker. +The map link that gets generated for Google & Apple maps has a push pin marking the users location. To enable detailed logging for this component, add the following to your configuration.yaml file logger: - default: warn + default: warning logs: custom_components.sensor.places: debug From 21bb51b08df387edd6e31f53bfc1654d3f3b43d8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 3 Sep 2022 17:48:27 -0400 Subject: [PATCH 098/329] Add OSM Map Link as option --- custom_components/places/sensor.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index ca988960..6772d9da 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -559,6 +559,10 @@ def do_update(self, reason): "https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=" + current_location ) + maplink_osm = ( + "https://www.openstreetmap.org/?mlat=" + + new_latitude + '&mlon=' + new_longitude + '#map=' + self._map_zoom + '/' + new_latitude[:8] + '/' + new_longitude[:9] + ) if ( new_latitude is not None and new_longitude is not None @@ -726,6 +730,8 @@ def do_update(self, reason): if self._map_provider == "google": self._map_link = maplink_google + elif self._map_provider == 'osm': + self._map_link = maplink_osm else: self._map_link = maplink_apple _LOGGER.debug("(" + self._name + ") Map Link Type: " + self._map_provider) From d99e2ed3d301533504cc9707f57735883aeec9c4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 3 Sep 2022 17:50:17 -0400 Subject: [PATCH 099/329] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e66a0852..05c7b7bf 100644 --- a/README.md +++ b/README.md @@ -92,11 +92,11 @@ Key | Type | Required | Description | Default | `name` | `string` | `False` | Friendly name of the sensor | `places` `home_zone` | `string` | `False` | Calculates distance from home and direction of travel if set | `zone.home` `api_key` | `string` | `False` | OpenStreetMap API key (your email address). | `no key` -`map_provider` | `string` | `False` | `google` or `apple` | `apple` +`map_provider` | `string` | `False` | `google`, `apple`, `osm` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` `language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s). | *Refer to Notes -`extended_attr` | `boolean` | `False` | Show extended attributes: `wikidata_id, osm_dict, osm_details_dict, wikidata_dict` (if they exist). Provides many additional attributes for advanced logic. Warning, will make the attributes very long! | `False` -`options` | `string` | `False` | Display options: `formatted_place (exclusive option), driving (can be used with formatted_place or other options), zone or zone_name, place, place_name, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home` | `zone, place` +`extended_attr` | `boolean` | `False` | Show extended attributes: wikidata_id, osm_dict, osm_details_dict, wikidata_dict *(if they exist)*. Provides many additional attributes for advanced logic. **Warning, will make the attributes very long!** | `False` +`options` | `string` | `False` | Display options: `formatted_place` *(exclusive option)*, `driving` *(can be used with formatted_place or other options)*, `zone` or `zone_name`, `place`, `place_name`, `street_number`, `street`, `city`, `county`, `state`, `postal_code`, `country`, `formatted_address`, `do_not_show_not_home` | `zone`, `place` Sample attributes that can be used in notifications, alerts, automations, etc: ```json From 580bcbef969a7a10400723ef20aec62703ecef43 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 3 Sep 2022 18:13:56 -0400 Subject: [PATCH 100/329] Declare variable --- custom_components/places/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6772d9da..62ff5c76 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -518,6 +518,7 @@ def do_update(self, reason): home_location = None maplink_apple = None maplink_google = None + maplink_osm = None _LOGGER.info("(" + self._name + ") Calling update due to " + reason) _LOGGER.info( From 9e969aa6e935f3ca9fb30c6a3aa01518c3bd44f6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 11:13:03 -0400 Subject: [PATCH 101/329] :art: Format Python code with Black Code Formatter (#61) --- custom_components/places/sensor.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 62ff5c76..5b6de229 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -562,7 +562,15 @@ def do_update(self, reason): ) maplink_osm = ( "https://www.openstreetmap.org/?mlat=" - + new_latitude + '&mlon=' + new_longitude + '#map=' + self._map_zoom + '/' + new_latitude[:8] + '/' + new_longitude[:9] + + new_latitude + + "&mlon=" + + new_longitude + + "#map=" + + self._map_zoom + + "/" + + new_latitude[:8] + + "/" + + new_longitude[:9] ) if ( new_latitude is not None @@ -731,7 +739,7 @@ def do_update(self, reason): if self._map_provider == "google": self._map_link = maplink_google - elif self._map_provider == 'osm': + elif self._map_provider == "osm": self._map_link = maplink_osm else: self._map_link = maplink_apple From f58653fe3078a10bfc9d6c9469f4823966f404d4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 12:08:06 -0400 Subject: [PATCH 102/329] Remove dashes for blank attributes If blank, the attribute just wont show in the Home Assistant sensor --- custom_components/places/sensor.py | 57 +++++++++++++++--------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5b6de229..9aea32e4 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -776,22 +776,22 @@ def do_update(self, reason): osm_decoded = json.loads(osm_json_input) place_options = self._options.lower() - place_type = "-" - place_name = "-" - place_category = "-" - place_neighbourhood = "-" - street_number = "" - street = "Unnamed Road" - city = "-" - postal_town = "-" - region = "-" - state_abbr = "-" - county = "-" - country = "-" - postal_code = "" - formatted_address = "" - target_option = "" - formatted_place = "" + place_type = None + place_name = None + place_category = None + place_neighbourhood = None + street_number = None + street = None + city = None + postal_town = None + region = None + state_abbr = None + county = None + country = None + postal_code = None + formatted_address = None + target_option = None + formatted_place = None osm_id = None osm_type = None wikidata_id = None @@ -880,7 +880,8 @@ def do_update(self, reason): self._postal_code = postal_code self._formatted_address = formatted_address self._mtime = str(datetime.now()) - self._osm_id = str(osm_id) + if osm_id is not None: + self._osm_id = str(osm_id) self._osm_type = osm_type isDriving = False @@ -907,9 +908,9 @@ def do_update(self, reason): ): formatted_place_array.append("Driving") isDriving = True - if self._place_name == "-": + if self._place_name is None: if ( - self._place_type != "-" + self._place_type is not None and self._place_type.lower() != "unclassified" and self._place_category.lower() != "highway" ): @@ -920,14 +921,14 @@ def do_update(self, reason): .strip() ) elif ( - self._place_category != "-" + self._place_category is not None and self._place_category.lower() != "highway" ): formatted_place_array.append( self._place_category.title().strip() ) - if self._street.lower() != "unnamed road" and self._street != "-": - if self._street_number == "-": + if self._street is not None: + if self._street_number is None: formatted_place_array.append(self._street.strip()) else: formatted_place_array.append( @@ -935,19 +936,19 @@ def do_update(self, reason): ) if ( self._place_type.lower() == "house" - and self._place_neighbourhood != "-" + and self._place_neighbourhood is not None ): formatted_place_array.append(self._place_neighbourhood.strip()) else: formatted_place_array.append(self._place_name.strip()) - if self._city != "-": + if self._city is not None: formatted_place_array.append( self._city.replace(" Township", "").strip() ) - elif self._county != "-": + elif self._county is not None: formatted_place_array.append(self._county.strip()) - if self._region != "-": + if self._state_abbr is not None: formatted_place_array.append(self._state_abbr) else: formatted_place_array.append(devicetracker_zone_name.strip()) @@ -1002,10 +1003,10 @@ def do_update(self, reason): user_display.append(self._devicetracker_zone) if "place_name" in display_options: - if place_name != "-": + if place_name is not None: user_display.append(place_name) if "place" in display_options: - if place_name != "-": + if place_name is not None: user_display.append(place_name) if place_category.lower() != "place": user_display.append(place_category) From 5868d1ab31582b834a7d3e2b46681411e024825d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 12:13:17 -0400 Subject: [PATCH 103/329] Update documentation --- README.md | 1 - custom_components/places/sensor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/README.md b/README.md index 05c7b7bf..ada7efcc 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,6 @@ Sample attributes that can be used in notifications, alerts, automations, etc: { "formatted_address": "Richmond Hill GO Station, 6, Newkirk Road, Beverley Acres, Richmond Hill, York Region, Ontario, L4C 1B3, Canada", "friendly_name": "sharon", - "postal_town": "-", "current_latitude": "43.874149009154095", "distance_from_home_km": "7.24 km", "country": "Canada", diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 9aea32e4..423b9c81 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -16,7 +16,6 @@ { "formatted_address": "Richmond Hill GO Station, 6, Newkirk Road, Beverley Acres, Richmond Hill, York Region, Ontario, L4C 1B3, Canada", "friendly_name": "sharon", - "postal_town": "-", "current_latitude": "43.874149009154095", "distance_from_home_km": "7.24 km", "country": "Canada", From 25810f0fa8f11a98349a8eb8e5642424795ced63 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 12:37:00 -0400 Subject: [PATCH 104/329] Change distance from home km into float Was previously a string with km at the end. Changing to a float. --- custom_components/places/sensor.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5b6de229..3c813186 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -18,7 +18,7 @@ "friendly_name": "sharon", "postal_town": "-", "current_latitude": "43.874149009154095", - "distance_from_home_km": "7.24 km", + "distance_from_home_km": 7.24, "country": "Canada", "postal_code": "L4C 1B3", "direction_of_travel": "towards home", @@ -97,7 +97,7 @@ message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home }} from home and traveling {{ trigger.event.data.direction }} + {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) data: attachment: @@ -119,7 +119,7 @@ message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home }} from home and traveling {{ trigger.event.data.direction }} + {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) data: attachment: @@ -584,8 +584,7 @@ def do_update(self, reason): float(home_latitude), float(home_longitude), ) - distance_km = round(distance_m / 1000, 2) - distance_from_home = str(distance_km) + " km" + distance_km = round(distance_m / 1000, 3) deviation = self.haversine( float(old_latitude), @@ -615,7 +614,8 @@ def do_update(self, reason): + ") Distance from home [" + (self._home_zone).split(".")[1] + "]: " - + distance_from_home + + str(distance_km) + + " km" ) _LOGGER.info("(" + self._name + ") Travel Direction: " + direction) @@ -733,7 +733,7 @@ def do_update(self, reason): self._location_previous = previous_location self._devicetracker_zone = devicetracker_zone self._devicetracker_zone_name = devicetracker_zone_name - self._distance_km = distance_from_home + self._distance_km = distance_km self._distance_m = distance_m self._direction = direction @@ -1198,8 +1198,10 @@ def do_update(self, reason): event_data["place_name"] = place_name if current_time is not None: event_data["mtime"] = current_time - if distance_from_home is not None: - event_data["distance_from_home"] = distance_from_home + if distance_km is not None: + event_data[ATTR_DISTANCE_KM] = distance_km + if distance_m is not None: + event_data[ATTR_DISTANCE_KM] = distance_m if direction is not None: event_data["direction"] = direction if devicetracker_zone is not None: From f0b4fff77eaa616822bbd42d7633cc52cf0981f2 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 12:44:46 -0400 Subject: [PATCH 105/329] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 05c7b7bf..b2e6e445 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Sample attributes that can be used in notifications, alerts, automations, etc: "friendly_name": "sharon", "postal_town": "-", "current_latitude": "43.874149009154095", - "distance_from_home_km": "7.24 km", + "distance_from_home_km": 7.24, "country": "Canada", "postal_code": "L4C 1B3", "direction_of_travel": "towards home", @@ -150,7 +150,7 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home }} from home and traveling {{ trigger.event.data.direction }} + {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) data: attachment: @@ -172,7 +172,7 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home }} from home and traveling {{ trigger.event.data.direction }} + {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) data: attachment: From d1f41ee3bf563adb034163fa137d9b0ed6f95438 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 13:13:15 -0400 Subject: [PATCH 106/329] Update Event Data to use Attribute Names ## Event Data Changes | Old Attribute | New Attribute | |---|---| | `direction` | `direction_of_travel` | | `latitude` | `current_latitude` | | `longitude` | `current_longitude` | | `mtime` | `last_changed` | | `map` | `map_link` | --- custom_components/places/sensor.py | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5b6de229..29dfaa72 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1195,40 +1195,40 @@ def do_update(self, reason): event_data["to_state"] = new_state if place_name is not None: - event_data["place_name"] = place_name + event_data[ATTR_PLACE_NAME] = place_name if current_time is not None: - event_data["mtime"] = current_time + event_data[ATTR_MTIME] = current_time if distance_from_home is not None: event_data["distance_from_home"] = distance_from_home if direction is not None: - event_data["direction"] = direction + event_data[ATTR_DIRECTION_OF_TRAVEL] = direction if devicetracker_zone is not None: - event_data["devicetracker_zone"] = devicetracker_zone + event_data[ATTR_DEVICETRACKER_ZONE] = devicetracker_zone if devicetracker_zone_name is not None: - event_data["devicetracker_zone_name"] = devicetracker_zone_name + event_data[ATTR_DEVICETRACKER_ZONE_NAME] = devicetracker_zone_name if self._latitude is not None: - event_data["latitude"] = self._latitude + event_data[ATTR_LATITUDE] = self._latitude if self._longitude is not None: - event_data["longitude"] = self._longitude + event_data[ATTR_LONGITUDE] = self._longitude if self._latitude_old is not None: - event_data["previous_latitude"] = self._latitude_old + event_data[ATTR_LATITUDE_OLD] = self._latitude_old if self._longitude_old is not None: - event_data["previous_longitude"] = self._longitude_old + event_data[ATTR_LONGITUDE_OLD] = self._longitude_old if self._map_link is not None: - event_data["map"] = self._map_link + event_data[ATTR_MAP_LINK] = self._map_link if osm_id is not None: - event_data["osm_id"] = osm_id + event_data[ATTR_OSM_ID] = osm_id if osm_type is not None: - event_data["osm_type"] = osm_type + event_data[ATTR_OSM_TYPE] = osm_type if self._extended_attr: if wikidata_id is not None: - event_data["wikidata_id"] = wikidata_id + event_data[ATTR_WIKIDATA_ID] = wikidata_id if osm_decoded is not None: - event_data["osm_dict"] = osm_decoded + event_data[ATTR_OSM_DICT] = osm_decoded if osm_details_dict is not None: - event_data["osm_details_dict"] = osm_details_dict + event_data[ATTR_OSM_DETAILS_DICT] = osm_details_dict if wikidata_dict is not None: - event_data["wikidata_dict"] = wikidata_dict + event_data[ATTR_WIKIDATA_DICT] = wikidata_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) _LOGGER.debug("(" + self._name + ") EventData update complete") From fe925c32ac9e842c548d0b135540563a72e53da0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 13:21:12 -0400 Subject: [PATCH 107/329] Create last_place_name attribute Will show zone if device_tracker was in a zone or place_name if location had a place_name. Will persist to show the last zone/place_name and should not be blank. --- custom_components/places/sensor.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5b6de229..dd406370 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -220,6 +220,7 @@ ATTR_OSM_DICT = "osm_dict" ATTR_OSM_DETAILS_DICT = "osm_details_dict" ATTR_WIKIDATA_DICT = "wikidata_dict" +ATTR_LAST_PLACE_NAME = "last_place_name" DEFAULT_NAME = "places" DEFAULT_OPTION = "zone, place" @@ -342,6 +343,7 @@ def __init__( self._devicetracker_zone = "Home" self._devicetracker_zone_name = "Home" self._mtime = str(datetime.now()) + self._last_place_name = None self._distance_km = 0 self._distance_m = 0 self._location_current = home_latitude + "," + home_longitude @@ -447,6 +449,8 @@ def extra_state_attributes(self): return_attr[ATTR_DISTANCE_M] = self._distance_m if self._mtime is not None: return_attr[ATTR_MTIME] = self._mtime + if self._last_place_name is not None: + return_attr[ATTR_LAST_PLACE_NAME] = self._last_place_name if self._location_current is not None: return_attr[ATTR_LOCATION_CURRENT] = self._location_current if self._location_previous is not None: @@ -519,6 +523,7 @@ def do_update(self, reason): maplink_apple = None maplink_google = None maplink_osm = None + last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to " + reason) _LOGGER.info( @@ -548,6 +553,17 @@ def do_update(self, reason): current_location = new_latitude + "," + new_longitude previous_location = old_latitude + "," + old_longitude home_location = home_latitude + "," + home_longitude + if ( + "stationary" in self._devicetracker_zone.lower() + or self._devicetracker_zone.lower() == "away" + or self._devicetracker_zone.lower() == "not_home" + ): + if self._place_name is not None: + last_place_name = self._place_name + else: + last_place_name = self._last_place_name + else: + last_place_name = self._devicetracker_zone_name maplink_apple = ( "https://maps.apple.com/maps/?q=" @@ -736,6 +752,7 @@ def do_update(self, reason): self._distance_km = distance_from_home self._distance_m = distance_m self._direction = direction + self._last_place_name = last_place_name if self._map_provider == "google": self._map_link = maplink_google @@ -1198,6 +1215,8 @@ def do_update(self, reason): event_data["place_name"] = place_name if current_time is not None: event_data["mtime"] = current_time + if last_place_name is not None: + event_data[ATTR_LAST_PLACE_NAME] = last_place_name if distance_from_home is not None: event_data["distance_from_home"] = distance_from_home if direction is not None: @@ -1254,6 +1273,7 @@ def _reset_attributes(self): self._place_type = None self._place_name = None self._mtime = datetime.now() + self._last_place_name = None self._osm_id = None self._osm_type = None self._wikidata_id = None From 3a24842cd0992659d36cdb49869b43632b2616e5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 14:26:55 -0400 Subject: [PATCH 108/329] Debug Logging --- custom_components/places/sensor.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index dd406370..7269cbc2 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -564,6 +564,9 @@ def do_update(self, reason): last_place_name = self._last_place_name else: last_place_name = self._devicetracker_zone_name + _LOGGER.debug( + "(" + self._name + ") Last Place Name: " + last_place_name + ) maplink_apple = ( "https://maps.apple.com/maps/?q=" From 6e783de1a88568add64d9da04e555d6a45bc5c4d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 14:47:29 -0400 Subject: [PATCH 109/329] Make last_place_name persist better --- custom_components/places/sensor.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 7269cbc2..815d3a55 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -553,16 +553,21 @@ def do_update(self, reason): current_location = new_latitude + "," + new_longitude previous_location = old_latitude + "," + old_longitude home_location = home_latitude + "," + home_longitude + if ( "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home" ): + #Not in a Zone if self._place_name is not None: + #If place name is set last_place_name = self._place_name else: + # If blank, keep previous last place name last_place_name = self._last_place_name else: + # In a Zone last_place_name = self._devicetracker_zone_name _LOGGER.debug( "(" + self._name + ") Last Place Name: " + last_place_name @@ -755,7 +760,6 @@ def do_update(self, reason): self._distance_km = distance_from_home self._distance_m = distance_m self._direction = direction - self._last_place_name = last_place_name if self._map_provider == "google": self._map_link = maplink_google @@ -902,6 +906,10 @@ def do_update(self, reason): self._mtime = str(datetime.now()) self._osm_id = str(osm_id) self._osm_type = osm_type + if last_place_name == place_name or last_place_name == devicetracker_zone_name: + # If current place name/zone are the same as previous, keep older last place name + last_place_name = self._last_place_name + self._last_place_name = last_place_name isDriving = False From 8de59074a6ab0edd08b6784f46a4383a274b4574 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 4 Sep 2022 14:59:36 -0400 Subject: [PATCH 110/329] Update debug logging --- custom_components/places/sensor.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 815d3a55..6ba411e9 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -508,6 +508,9 @@ def haversine(self, lon1, lat1, lon2, lat2): def do_update(self, reason): """Get the latest data and updates the states.""" + _LOGGER.debug( + "(" + self._name + ") Starting Update..." + str(last_place_name) + ) previous_state = self.state distance_traveled = 0 devicetracker_zone = None @@ -553,25 +556,29 @@ def do_update(self, reason): current_location = new_latitude + "," + new_longitude previous_location = old_latitude + "," + old_longitude home_location = home_latitude + "," + home_longitude - + _LOGGER.debug("(" + self._name + ") Previous last_place_name: " + str(self._last_place_name)) + if ( "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home" ): #Not in a Zone - if self._place_name is not None: + if self._place_name is not None and self._place_name != "-": #If place name is set last_place_name = self._place_name + _LOGGER.debug("(" + self._name + ") Previous Place Name is set: " + last_place_name + ", updating") else: # If blank, keep previous last place name last_place_name = self._last_place_name + _LOGGER.debug("(" + self._name + ") Previous Place Name is None or -, keeping prior") else: # In a Zone last_place_name = self._devicetracker_zone_name + _LOGGER.debug("(" + self._name + ") Previous Place is Zone: " + last_place_name + ", updating") _LOGGER.debug( - "(" + self._name + ") Last Place Name: " + last_place_name - ) + "(" + self._name + ") Last Place Name (Initial): " + str(last_place_name) + ) maplink_apple = ( "https://maps.apple.com/maps/?q=" @@ -909,7 +916,13 @@ def do_update(self, reason): if last_place_name == place_name or last_place_name == devicetracker_zone_name: # If current place name/zone are the same as previous, keep older last place name last_place_name = self._last_place_name + _LOGGER.debug("(" + self._name + ") Initial last_place_name is same as new: place_name=" + place_name + " or devicetracker_zone_name=" + devicetracker_zone_name+ ", keeping previous last_place_name") + else: + _LOGGER.debug("(" + self._name + ") Keeping initial last_place_name") self._last_place_name = last_place_name + _LOGGER.debug( + "(" + self._name + ") Last Place Name (Final): " + str(last_place_name) + ) isDriving = False @@ -1268,7 +1281,10 @@ def do_update(self, reason): + self._name + ") No entity update needed, Previous State = New State" ) - + _LOGGER.debug( + "(" + self._name + ") End of Update" + str(last_place_name) + ) + def _reset_attributes(self): """Resets attributes.""" self._street = None From f344ef44ce7b382ec5ba3915927710274c004998 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 11:43:03 -0400 Subject: [PATCH 111/329] Don't update last_place_name on initial update --- custom_components/places/sensor.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6ba411e9..5a8e64df 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -708,6 +708,7 @@ def do_update(self, reason): ) proceed_with_update = True + initial_update = False if current_location == previous_location: _LOGGER.debug( @@ -737,6 +738,7 @@ def do_update(self, reason): if previous_state == "Initializing...": _LOGGER.debug("(" + self._name + ") Performing Initial Update for user...") proceed_with_update = True + initial_update = True if proceed_with_update and devicetracker_zone: _LOGGER.debug( @@ -913,7 +915,10 @@ def do_update(self, reason): self._mtime = str(datetime.now()) self._osm_id = str(osm_id) self._osm_type = osm_type - if last_place_name == place_name or last_place_name == devicetracker_zone_name: + if initial_update == True: + last_place_name = self._last_place_name + _LOGGER.debug("(" + self._name + ") Runnining initial update after load, using prior last_place_name") + elif last_place_name == place_name or last_place_name == devicetracker_zone_name: # If current place name/zone are the same as previous, keep older last place name last_place_name = self._last_place_name _LOGGER.debug("(" + self._name + ") Initial last_place_name is same as new: place_name=" + place_name + " or devicetracker_zone_name=" + devicetracker_zone_name+ ", keeping previous last_place_name") From 4e4dcb9b3b102a4ffa61b34e7010f919cc4e222a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 11:50:51 -0400 Subject: [PATCH 112/329] Update debug logging --- custom_components/places/sensor.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5a8e64df..7845de14 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -509,8 +509,7 @@ def do_update(self, reason): """Get the latest data and updates the states.""" _LOGGER.debug( - "(" + self._name + ") Starting Update..." + str(last_place_name) - ) + "(" + self._name + ") Starting Update...") previous_state = self.state distance_traveled = 0 devicetracker_zone = None @@ -1287,8 +1286,7 @@ def do_update(self, reason): + ") No entity update needed, Previous State = New State" ) _LOGGER.debug( - "(" + self._name + ") End of Update" + str(last_place_name) - ) + "(" + self._name + ") End of Update") def _reset_attributes(self): """Resets attributes.""" From 0cb8aa756496506b8e9e1a9b58da9bff89da6973 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 12:45:22 -0400 Subject: [PATCH 113/329] Don't reset last_place_name when resetting attributes --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 7845de14..95476df5 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1303,7 +1303,7 @@ def _reset_attributes(self): self._place_type = None self._place_name = None self._mtime = datetime.now() - self._last_place_name = None + #self._last_place_name = None self._osm_id = None self._osm_type = None self._wikidata_id = None From 224610b15e154f57360c3df0e7d4fa7b4c4c5f28 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 14:30:21 -0400 Subject: [PATCH 114/329] Only send last_place_name in Event when changed --- custom_components/places/sensor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 95476df5..a5146263 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -526,6 +526,7 @@ def do_update(self, reason): maplink_google = None maplink_osm = None last_place_name = None + prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to " + reason) _LOGGER.info( @@ -555,6 +556,7 @@ def do_update(self, reason): current_location = new_latitude + "," + new_longitude previous_location = old_latitude + "," + old_longitude home_location = home_latitude + "," + home_longitude + prev_last_place_name = self._last_place_name _LOGGER.debug("(" + self._name + ") Previous last_place_name: " + str(self._last_place_name)) if ( @@ -1243,7 +1245,7 @@ def do_update(self, reason): event_data["place_name"] = place_name if current_time is not None: event_data["mtime"] = current_time - if last_place_name is not None: + if last_place_name is not None and last_place_name != prev_last_place_name: event_data[ATTR_LAST_PLACE_NAME] = last_place_name if distance_from_home is not None: event_data["distance_from_home"] = distance_from_home From 1fb8d090b0c47db9572c3df80578bc327dcb96a5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 15:31:54 -0400 Subject: [PATCH 115/329] Update debug logging --- custom_components/places/sensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a5146263..7854f24c 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -508,7 +508,7 @@ def haversine(self, lon1, lat1, lon2, lat2): def do_update(self, reason): """Get the latest data and updates the states.""" - _LOGGER.debug( + _LOGGER.info( "(" + self._name + ") Starting Update...") previous_state = self.state distance_traveled = 0 @@ -1280,14 +1280,14 @@ def do_update(self, reason): event_data["wikidata_dict"] = wikidata_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) - _LOGGER.debug("(" + self._name + ") EventData update complete") + _LOGGER.debug("(" + self._name + ") EventData updated: " + str(event_data)) else: _LOGGER.debug( "(" + self._name + ") No entity update needed, Previous State = New State" ) - _LOGGER.debug( + _LOGGER.info( "(" + self._name + ") End of Update") def _reset_attributes(self): From a38fa27c5ae6d99e108627594114a5c5d8233c98 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 16:08:00 -0400 Subject: [PATCH 116/329] :art: Format Python code with Black Code Formatter (#66) --- custom_components/places/sensor.py | 78 +++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e7e828ea..03355b30 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -507,8 +507,7 @@ def haversine(self, lon1, lat1, lon2, lat2): def do_update(self, reason): """Get the latest data and updates the states.""" - _LOGGER.info( - "(" + self._name + ") Starting Update...") + _LOGGER.info("(" + self._name + ") Starting Update...") previous_state = self.state distance_traveled = 0 devicetracker_zone = None @@ -556,28 +555,52 @@ def do_update(self, reason): previous_location = old_latitude + "," + old_longitude home_location = home_latitude + "," + home_longitude prev_last_place_name = self._last_place_name - _LOGGER.debug("(" + self._name + ") Previous last_place_name: " + str(self._last_place_name)) + _LOGGER.debug( + "(" + + self._name + + ") Previous last_place_name: " + + str(self._last_place_name) + ) if ( "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home" ): - #Not in a Zone + # Not in a Zone if self._place_name is not None and self._place_name != "-": - #If place name is set + # If place name is set last_place_name = self._place_name - _LOGGER.debug("(" + self._name + ") Previous Place Name is set: " + last_place_name + ", updating") + _LOGGER.debug( + "(" + + self._name + + ") Previous Place Name is set: " + + last_place_name + + ", updating" + ) else: # If blank, keep previous last place name last_place_name = self._last_place_name - _LOGGER.debug("(" + self._name + ") Previous Place Name is None or -, keeping prior") + _LOGGER.debug( + "(" + + self._name + + ") Previous Place Name is None or -, keeping prior" + ) else: # In a Zone last_place_name = self._devicetracker_zone_name - _LOGGER.debug("(" + self._name + ") Previous Place is Zone: " + last_place_name + ", updating") + _LOGGER.debug( + "(" + + self._name + + ") Previous Place is Zone: " + + last_place_name + + ", updating" + ) _LOGGER.debug( - "(" + self._name + ") Last Place Name (Initial): " + str(last_place_name) + "(" + + self._name + + ") Last Place Name (Initial): " + + str(last_place_name) ) maplink_apple = ( @@ -918,11 +941,26 @@ def do_update(self, reason): self._osm_type = osm_type if initial_update == True: last_place_name = self._last_place_name - _LOGGER.debug("(" + self._name + ") Runnining initial update after load, using prior last_place_name") - elif last_place_name == place_name or last_place_name == devicetracker_zone_name: + _LOGGER.debug( + "(" + + self._name + + ") Runnining initial update after load, using prior last_place_name" + ) + elif ( + last_place_name == place_name + or last_place_name == devicetracker_zone_name + ): # If current place name/zone are the same as previous, keep older last place name last_place_name = self._last_place_name - _LOGGER.debug("(" + self._name + ") Initial last_place_name is same as new: place_name=" + place_name + " or devicetracker_zone_name=" + devicetracker_zone_name+ ", keeping previous last_place_name") + _LOGGER.debug( + "(" + + self._name + + ") Initial last_place_name is same as new: place_name=" + + place_name + + " or devicetracker_zone_name=" + + devicetracker_zone_name + + ", keeping previous last_place_name" + ) else: _LOGGER.debug("(" + self._name + ") Keeping initial last_place_name") self._last_place_name = last_place_name @@ -1245,7 +1283,10 @@ def do_update(self, reason): event_data[ATTR_PLACE_NAME] = place_name if current_time is not None: event_data[ATTR_MTIME] = current_time - if last_place_name is not None and last_place_name != prev_last_place_name: + if ( + last_place_name is not None + and last_place_name != prev_last_place_name + ): event_data[ATTR_LAST_PLACE_NAME] = last_place_name if distance_from_home is not None: event_data["distance_from_home"] = distance_from_home @@ -1285,16 +1326,17 @@ def do_update(self, reason): event_data[ATTR_WIKIDATA_DICT] = wikidata_dict # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) - _LOGGER.debug("(" + self._name + ") EventData updated: " + str(event_data)) + _LOGGER.debug( + "(" + self._name + ") EventData updated: " + str(event_data) + ) else: _LOGGER.debug( "(" + self._name + ") No entity update needed, Previous State = New State" ) - _LOGGER.info( - "(" + self._name + ") End of Update") - + _LOGGER.info("(" + self._name + ") End of Update") + def _reset_attributes(self): """Resets attributes.""" self._street = None @@ -1310,7 +1352,7 @@ def _reset_attributes(self): self._place_type = None self._place_name = None self._mtime = datetime.now() - #self._last_place_name = None + # self._last_place_name = None self._osm_id = None self._osm_type = None self._wikidata_id = None From f530cdf6e968956107ba3449a0434f256da6eaa6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 16:14:06 -0400 Subject: [PATCH 117/329] Fixing merge issue --- custom_components/places/sensor.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 03355b30..e9c50096 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -1288,9 +1288,6 @@ def do_update(self, reason): and last_place_name != prev_last_place_name ): event_data[ATTR_LAST_PLACE_NAME] = last_place_name - if distance_from_home is not None: - event_data["distance_from_home"] = distance_from_home - if distance_km is not None: event_data[ATTR_DISTANCE_KM] = distance_km if distance_m is not None: From 400a649e86f2abaa5f798ea9ba7e6d080017b87d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 16:20:19 -0400 Subject: [PATCH 118/329] Update debug logging --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e9c50096..42ca778f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -956,9 +956,9 @@ def do_update(self, reason): "(" + self._name + ") Initial last_place_name is same as new: place_name=" - + place_name + + str(place_name) + " or devicetracker_zone_name=" - + devicetracker_zone_name + + str(devicetracker_zone_name) + ", keeping previous last_place_name" ) else: From ab5cb23473c0247e3240a07ceca8881549ae6caf Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 16:37:45 -0400 Subject: [PATCH 119/329] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1f0ffa9e..21b0efe1 100644 --- a/README.md +++ b/README.md @@ -149,11 +149,11 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} - {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) + {{ trigger.event.data.distance_from_home_km }} km from home and traveling {{ trigger.event.data.direction_of_travel }} + {{ trigger.event.data.to_state }} ({{ trigger.event.data.last_changed }}) data: attachment: - url: '{{ trigger.event.data.map }}' + url: '{{ trigger.event.data.map_link }}' hide_thumbnail: false - alias: ReverseLocateAidan @@ -171,11 +171,11 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} - {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) + {{ trigger.event.data.distance_from_home_km }} km from home and traveling {{ trigger.event.data.direction_of_travel }} + {{ trigger.event.data.to_state }} ({{ trigger.event.data.last_changed }}) data: attachment: - url: '{{ trigger.event.data.map }}' + url: '{{ trigger.event.data.map_link }}' hide_thumbnail: false ``` From a87eefa5f3d4f222e0c169d7d1f5d00857a31f1a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 17:03:27 -0400 Subject: [PATCH 120/329] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 21b0efe1..d869e6c5 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ _Component to integrate with OpenStreetMap Reverse Geocode (PLACE)_ ### Installation via HACS -Unless you have a good reason not to, you probably want to install this component via HACS(Home Assistant Community Store) +Unless you have a good reason not to, you probably want to install this component via HACS (Home Assistant Community Store) 1. Ensure that [HACS](https://hacs.xyz/) is installed. 1. Navigate to HACS -> Integrations 1. Open the three-dot menu and select 'Custom Repositories' From 053e689b22de560729c256c35366a07326003f9f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 17:16:57 -0400 Subject: [PATCH 121/329] Update black_action.yml --- .github/workflows/black_action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/black_action.yml b/.github/workflows/black_action.yml index 21b3e0f7..6142c3a8 100644 --- a/.github/workflows/black_action.yml +++ b/.github/workflows/black_action.yml @@ -23,6 +23,7 @@ jobs: body: | There appear to be some python formatting errors in ${{ github.sha }}. This pull request uses the [Black Code Formatter](/~https://github.com/psf/black) to fix these issues. + labels: automerge base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true branch: actions/black From 9111b937288f31d75b09b460bad139a70387d2d7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 17:47:44 -0400 Subject: [PATCH 122/329] Update black_action.yml --- .github/workflows/black_action.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/black_action.yml b/.github/workflows/black_action.yml index 6142c3a8..4a639bd7 100644 --- a/.github/workflows/black_action.yml +++ b/.github/workflows/black_action.yml @@ -5,9 +5,9 @@ jobs: name: Black Code Formatter runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.0.2 - name: Check files using the Black Code Formatter - uses: rickstaa/action-black@v1 + uses: rickstaa/action-black@v1.1.14 id: action_black with: black_args: "." @@ -15,7 +15,7 @@ jobs: - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' id: cpr - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v4.1.1 with: token: ${{ secrets.CPR }} title: "Format Python code with Black Code Formatter" @@ -27,3 +27,15 @@ jobs: base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true branch: actions/black + - name: Auto Merge + if: ${{ steps.cpr.outputs.pull-request-number }} + id: automerge + uses: pascalgn/automerge-action@v0.15.3 + env: + GITHUB_TOKEN: "${{ secrets.CPR }}" + MERGE_LABELS: "automerge" + MERGE_METHOD: "squash" + MERGE_REMOVE_LABELS: "automerge" + MERGE_DELETE_BRANCH: "true" + MERGE_ERROR_FAIL: "true" + From 81e53258ef5cde036de8f0acc6a2ee7400685baf Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 18:19:01 -0400 Subject: [PATCH 123/329] Update black_action.yml --- .github/workflows/black_action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/black_action.yml b/.github/workflows/black_action.yml index 4a639bd7..a8d91288 100644 --- a/.github/workflows/black_action.yml +++ b/.github/workflows/black_action.yml @@ -33,6 +33,7 @@ jobs: uses: pascalgn/automerge-action@v0.15.3 env: GITHUB_TOKEN: "${{ secrets.CPR }}" + PULL_REQUEST: "${{ steps.cpr.outputs.pull-request-number }}" MERGE_LABELS: "automerge" MERGE_METHOD: "squash" MERGE_REMOVE_LABELS: "automerge" From 223c87436f94ef81c50c99643b178731761faa9a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 18:29:54 -0400 Subject: [PATCH 124/329] Update black_action.yml --- .github/workflows/black_action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/black_action.yml b/.github/workflows/black_action.yml index a8d91288..b9cc3bba 100644 --- a/.github/workflows/black_action.yml +++ b/.github/workflows/black_action.yml @@ -23,7 +23,7 @@ jobs: body: | There appear to be some python formatting errors in ${{ github.sha }}. This pull request uses the [Black Code Formatter](/~https://github.com/psf/black) to fix these issues. - labels: automerge + labels: "automerge,black" base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true branch: actions/black @@ -36,7 +36,7 @@ jobs: PULL_REQUEST: "${{ steps.cpr.outputs.pull-request-number }}" MERGE_LABELS: "automerge" MERGE_METHOD: "squash" - MERGE_REMOVE_LABELS: "automerge" + MERGE_REMOVE_LABELS: "automerge,black" MERGE_DELETE_BRANCH: "true" MERGE_ERROR_FAIL: "true" From 94f7c3af9ab33713765ae59e4bb2f8c2ca70a789 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 18:30:54 -0400 Subject: [PATCH 125/329] Create release.yml --- .github/release.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..31b437c8 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,5 @@ +changelog: + exclude: + labels: + - ignore-for-release + - black From 07eae4b594e03d208d149f295ab4787a47c6582a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 22:12:36 -0400 Subject: [PATCH 126/329] Update black_action.yml --- .github/workflows/black_action.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/black_action.yml b/.github/workflows/black_action.yml index b9cc3bba..8dabc623 100644 --- a/.github/workflows/black_action.yml +++ b/.github/workflows/black_action.yml @@ -6,12 +6,16 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 - - name: Check files using the Black Code Formatter + - name: Check code with the Black Code Formatter uses: rickstaa/action-black@v1.1.14 id: action_black with: black_args: "." fail_on_error: 'true' + - name: Check code with isort + uses: jamescurtin/isort-action@master + with: + configuration: --force-single-line - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' id: cpr From 31890b687750049e5d6811b7df22a32bcd87670b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 22:23:44 -0400 Subject: [PATCH 127/329] Update and rename black_action.yml to mylint_action.yml --- .../{black_action.yml => mylint_action.yml} | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) rename .github/workflows/{black_action.yml => mylint_action.yml} (79%) diff --git a/.github/workflows/black_action.yml b/.github/workflows/mylint_action.yml similarity index 79% rename from .github/workflows/black_action.yml rename to .github/workflows/mylint_action.yml index 8dabc623..58014638 100644 --- a/.github/workflows/black_action.yml +++ b/.github/workflows/mylint_action.yml @@ -1,4 +1,4 @@ -name: Black Code Formatter +name: MyLint Code Updater (black, isort) on: [workflow_dispatch, pull_request] jobs: linter_name: @@ -22,15 +22,15 @@ jobs: uses: peter-evans/create-pull-request@v4.1.1 with: token: ${{ secrets.CPR }} - title: "Format Python code with Black Code Formatter" - commit-message: ":art: Format Python code with Black Code Formatter" + title: "Format Python code with isort & Black Code Formatter" + commit-message: ":art: Format Python code with isort & Black Code Formatter" body: | There appear to be some python formatting errors in ${{ github.sha }}. This pull request - uses the [Black Code Formatter](/~https://github.com/psf/black) to fix these issues. - labels: "automerge,black" + uses the [Black Code Formatter](/~https://github.com/psf/black) and isort to fix these issues. + labels: "automerge,black,isort" base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true - branch: actions/black + branch: actions/mylint - name: Auto Merge if: ${{ steps.cpr.outputs.pull-request-number }} id: automerge @@ -40,7 +40,7 @@ jobs: PULL_REQUEST: "${{ steps.cpr.outputs.pull-request-number }}" MERGE_LABELS: "automerge" MERGE_METHOD: "squash" - MERGE_REMOVE_LABELS: "automerge,black" + MERGE_REMOVE_LABELS: "automerge,black,isort" MERGE_DELETE_BRANCH: "true" MERGE_ERROR_FAIL: "true" From fe85fb7f85ef563df961aaaf22bf342524291f3e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 22:25:57 -0400 Subject: [PATCH 128/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 58014638..b655c289 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -2,7 +2,7 @@ name: MyLint Code Updater (black, isort) on: [workflow_dispatch, pull_request] jobs: linter_name: - name: Black Code Formatter + name: MyLint Code Updater (black, isort) runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 From 7718748e8029357a984a779e111708d1d6d210e6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 22:26:18 -0400 Subject: [PATCH 129/329] Update release.yml --- .github/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/release.yml b/.github/release.yml index 31b437c8..fa3fb0c9 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -3,3 +3,4 @@ changelog: labels: - ignore-for-release - black + - isort From 70068307d1988e373f9288659781707272dc2e71 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 22:34:37 -0400 Subject: [PATCH 130/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index b655c289..32a8082e 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -15,7 +15,7 @@ jobs: - name: Check code with isort uses: jamescurtin/isort-action@master with: - configuration: --force-single-line + configuration: --force-single-line --profile black - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' id: cpr @@ -26,7 +26,7 @@ jobs: commit-message: ":art: Format Python code with isort & Black Code Formatter" body: | There appear to be some python formatting errors in ${{ github.sha }}. This pull request - uses the [Black Code Formatter](/~https://github.com/psf/black) and isort to fix these issues. + uses the [Black Code Formatter](/~https://github.com/psf/black) and [isort](https://pycqa.github.io/isort) to fix these issues. labels: "automerge,black,isort" base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch delete-branch: true From ed6d07ed52578243432707e03aa26473c9bf1af8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 23:22:11 -0400 Subject: [PATCH 131/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 32a8082e..66cd1be3 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -6,6 +6,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 + - name: Set up Python environment + uses: actions/setup-python@v2 + with: + python-version: "3.10" - name: Check code with the Black Code Formatter uses: rickstaa/action-black@v1.1.14 id: action_black @@ -16,6 +20,11 @@ jobs: uses: jamescurtin/isort-action@master with: configuration: --force-single-line --profile black + - name: flake8 Lint + uses: py-actions/flake8@v2.2.0 + with: + path: "src" + plugins: "flake8-black" - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' id: cpr From 13029fc02babe89c3e287fbda72b636966bb59a3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 23:25:27 -0400 Subject: [PATCH 132/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 66cd1be3..89a5d6e2 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -23,7 +23,6 @@ jobs: - name: flake8 Lint uses: py-actions/flake8@v2.2.0 with: - path: "src" plugins: "flake8-black" - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' From fcef2b531e689dfc81034ab10e2b2b07a768a9d3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 5 Sep 2022 23:32:30 -0400 Subject: [PATCH 133/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 89a5d6e2..65445fae 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -21,9 +21,9 @@ jobs: with: configuration: --force-single-line --profile black - name: flake8 Lint - uses: py-actions/flake8@v2.2.0 + uses: reviewdog/action-flake8@v3 with: - plugins: "flake8-black" + github_token: ${{ secrets.GITHUB_TOKEN }} - name: Create Pull Request if: steps.action_black.outputs.is_formatted == 'true' id: cpr From f93922c3f8dc05d4af98d48b758599bdc8353939 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 17:52:47 -0400 Subject: [PATCH 134/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 65445fae..c013ebd7 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -18,14 +18,18 @@ jobs: fail_on_error: 'true' - name: Check code with isort uses: jamescurtin/isort-action@master + id: action_isort with: configuration: --force-single-line --profile black - - name: flake8 Lint + - name: Check code with flake8 uses: reviewdog/action-flake8@v3 + id: action_flake8 with: github_token: ${{ secrets.GITHUB_TOKEN }} + fail_on_error: false + flake8-args: "--select=F,E7,E9,W1,W6" - name: Create Pull Request - if: steps.action_black.outputs.is_formatted == 'true' + if: github.event_name == 'pull_request' && (steps.action_black.outputs.is_formatted == 'true' || steps.action_isort.outputs.isort-result) id: cpr uses: peter-evans/create-pull-request@v4.1.1 with: From e6bbcd342d9de3a203f3862487a4290a8ab42ad0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 18:11:29 -0400 Subject: [PATCH 135/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index c013ebd7..113f1655 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -27,7 +27,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} fail_on_error: false - flake8-args: "--select=F,E7,E9,W1,W6" + flake8_args: "--select=F,E7,E9,W1,W6" - name: Create Pull Request if: github.event_name == 'pull_request' && (steps.action_black.outputs.is_formatted == 'true' || steps.action_isort.outputs.isort-result) id: cpr From c1bfb642ab0a3920678843e733e708f6b031d1c0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 18:26:51 -0400 Subject: [PATCH 136/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 113f1655..779bbbcc 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -27,6 +27,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} fail_on_error: false + level: "info" flake8_args: "--select=F,E7,E9,W1,W6" - name: Create Pull Request if: github.event_name == 'pull_request' && (steps.action_black.outputs.is_formatted == 'true' || steps.action_isort.outputs.isort-result) From 24e6f699dc69dc3a0bdae9568608afb937f8a70a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 18:35:13 -0400 Subject: [PATCH 137/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 779bbbcc..6a0718ba 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -27,7 +27,7 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} fail_on_error: false - level: "info" + filter_mode: "nofilter" flake8_args: "--select=F,E7,E9,W1,W6" - name: Create Pull Request if: github.event_name == 'pull_request' && (steps.action_black.outputs.is_formatted == 'true' || steps.action_isort.outputs.isort-result) From 88018d3361c4b9845029af4cca2539c7b75e17d1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 18:43:05 -0400 Subject: [PATCH 138/329] Code Cleanup --- custom_components/places/sensor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 42ca778f..5b2868c9 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -157,7 +157,6 @@ from math import radians, cos, sin, asin, sqrt import voluptuous as vol -import homeassistant.helpers.location as location import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA @@ -939,7 +938,7 @@ def do_update(self, reason): if osm_id is not None: self._osm_id = str(osm_id) self._osm_type = osm_type - if initial_update == True: + if initial_update is True: last_place_name = self._last_place_name _LOGGER.debug( "(" From 2504bea8a1d6b0bb13415116ccae08653ca55e1f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 18:45:15 -0400 Subject: [PATCH 139/329] :art: Format Python code with isort & Black Code Formatter (#78) --- custom_components/places/sensor.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5b2868c9..dfd471df 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -151,20 +151,28 @@ """ -import logging, json, requests -from datetime import datetime, timedelta -from requests import get -from math import radians, cos, sin, asin, sqrt +import json +import logging +from datetime import datetime +from datetime import timedelta +from math import asin +from math import cos +from math import radians +from math import sin +from math import sqrt -import voluptuous as vol import homeassistant.helpers.config_validation as cv - +import requests +import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import CONF_API_KEY +from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_SCAN_INTERVAL +from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import track_state_change from homeassistant.util import Throttle from homeassistant.util.location import distance -from homeassistant.helpers.entity import Entity -from homeassistant.const import CONF_API_KEY, CONF_NAME, CONF_SCAN_INTERVAL +from requests import get _LOGGER = logging.getLogger(__name__) From 376e8d849e7bc39d0895ab6d7149f24cd4b225df Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 18:47:35 -0400 Subject: [PATCH 140/329] Update sensor.py --- custom_components/places/sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index dfd471df..751b0be6 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -162,7 +162,6 @@ from math import sqrt import homeassistant.helpers.config_validation as cv -import requests import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY From c79b898a9f34a3ad79d93e5edfc6cc32b558c11d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 6 Sep 2022 18:52:09 -0400 Subject: [PATCH 141/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 6a0718ba..884204ca 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -53,7 +53,7 @@ jobs: PULL_REQUEST: "${{ steps.cpr.outputs.pull-request-number }}" MERGE_LABELS: "automerge" MERGE_METHOD: "squash" - MERGE_REMOVE_LABELS: "automerge,black,isort" + MERGE_REMOVE_LABELS: "black,isort" MERGE_DELETE_BRANCH: "true" MERGE_ERROR_FAIL: "true" From 5acc99a2cffc3a8a1999b2c6e34140e74bf353f4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 17:29:05 -0400 Subject: [PATCH 142/329] Check if None before manipulating --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 751b0be6..4895a3a3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -899,7 +899,7 @@ def do_update(self, reason): city = osm_decoded["address"]["municipality"] elif "city_district" in osm_decoded["address"]: city = osm_decoded["address"]["city_district"] - if city.startswith("City of"): + if city is not None and city.startswith("City of"): city = city[8:] + " City" if "city_district" in osm_decoded["address"]: From ea69daedfcfba908f4c46cdfb457d42368138fb2 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:02:05 -0400 Subject: [PATCH 143/329] Create issue_action.yml --- .github/workflows/issue_action.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/issue_action.yml diff --git a/.github/workflows/issue_action.yml b/.github/workflows/issue_action.yml new file mode 100644 index 00000000..093ccc80 --- /dev/null +++ b/.github/workflows/issue_action.yml @@ -0,0 +1,14 @@ +on: + issues: + types: [ assigned ] + pull_request: + types: [ closed ] + +jobs: + create_issue_branch_job: + runs-on: ubuntu-latest + steps: + - name: Create Issue Branch + uses: robvanderleek/create-issue-branch@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 76ce42c8c7ca3595ebb82f8b01a79e3b2d3c3829 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:16:11 -0400 Subject: [PATCH 144/329] Update issue_action.yml --- .github/workflows/issue_action.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/issue_action.yml b/.github/workflows/issue_action.yml index 093ccc80..171ccc34 100644 --- a/.github/workflows/issue_action.yml +++ b/.github/workflows/issue_action.yml @@ -1,8 +1,6 @@ on: issues: types: [ assigned ] - pull_request: - types: [ closed ] jobs: create_issue_branch_job: From f070b40f5341b4ad03f47b93a2ec8b272962b7d7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:20:07 -0400 Subject: [PATCH 145/329] Create release_action.yml --- .github/workflows/release_action.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/workflows/release_action.yml diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml new file mode 100644 index 00000000..f84a0ebd --- /dev/null +++ b/.github/workflows/release_action.yml @@ -0,0 +1,4 @@ +on: + release: + types: [released] + From 6ee5caabb27b7810046babb9ce4dda32ad522c2e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:21:43 -0400 Subject: [PATCH 146/329] Update release_action.yml --- .github/workflows/release_action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index f84a0ebd..fc03d0e6 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -1,4 +1,5 @@ on: + workflow_dispatch: release: types: [released] From 3977955fc291108168c2dc65a38642a36671d4d0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:22:38 -0400 Subject: [PATCH 147/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 884204ca..f34c53ce 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -1,8 +1,8 @@ -name: MyLint Code Updater (black, isort) +name: MyLint Code Updater (black, isort, flake8) on: [workflow_dispatch, pull_request] jobs: linter_name: - name: MyLint Code Updater (black, isort) + name: MyLint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 From 9cba1e8e1b1490c45f5fb82eb68a554eec17b3d0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:23:21 -0400 Subject: [PATCH 148/329] Create issue-branch.yml --- .github/issue-branch.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/issue-branch.yml diff --git a/.github/issue-branch.yml b/.github/issue-branch.yml new file mode 100644 index 00000000..7286d39a --- /dev/null +++ b/.github/issue-branch.yml @@ -0,0 +1,13 @@ +mode: auto +silent: true +branchName: full +openDraftPR: true + +branches: + - label: bug + skip: false + prefix: bugfix/ + name: dev + prTarget: dev + - label: '*' + skip: true From c3561131855502c3243c638f849be9acad7b0315 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:24:16 -0400 Subject: [PATCH 149/329] Update release_action.yml --- .github/workflows/release_action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index fc03d0e6..1a85a971 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -1,3 +1,4 @@ +name: Create new Branch and Release on: workflow_dispatch: release: From 942998e2e67bd7a8e019c713ba835cee91887de7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:25:00 -0400 Subject: [PATCH 150/329] Update issue_action.yml --- .github/workflows/issue_action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/issue_action.yml b/.github/workflows/issue_action.yml index 171ccc34..d0940e52 100644 --- a/.github/workflows/issue_action.yml +++ b/.github/workflows/issue_action.yml @@ -1,3 +1,4 @@ +name: Create Branch on Assigning Bug Issue on: issues: types: [ assigned ] From 80717cc1168ba68ff134ea28ba32af424c1d4abc Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:25:27 -0400 Subject: [PATCH 151/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index f34c53ce..56dba07e 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -1,8 +1,7 @@ name: MyLint Code Updater (black, isort, flake8) on: [workflow_dispatch, pull_request] jobs: - linter_name: - name: MyLint + mylint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 From 676287ab3cf8d926cf4a7f3b508fcd9512b1b3b6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:27:01 -0400 Subject: [PATCH 152/329] Update release_action.yml --- .github/workflows/release_action.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 1a85a971..74dbac8e 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -4,3 +4,9 @@ on: release: types: [released] +uses: peterjgrainger/action-create-branch@v2.2.0 +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +with: + branch: 'dev' + sha: '${{ github.event.pull_request.head.sha }}' From 66e39db59be0a3db3246f80f81b2d961fb540422 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:27:36 -0400 Subject: [PATCH 153/329] Update release_action.yml --- .github/workflows/release_action.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 74dbac8e..dc994bb8 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -3,6 +3,14 @@ on: workflow_dispatch: release: types: [released] +jobs: + + mylint: + + runs-on: ubuntu-latest + + steps: + uses: peterjgrainger/action-create-branch@v2.2.0 env: From 43604e1eca1d7891dfff4fdc454409d7a1fd482f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:31:59 -0400 Subject: [PATCH 154/329] Update release_action.yml --- .github/workflows/release_action.yml | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index dc994bb8..d2248acc 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -4,17 +4,25 @@ on: release: types: [released] jobs: + new_release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 - mylint: - runs-on: ubuntu-latest - steps: + + - name: Create new dev branch + if: ${{ steps.cpr.outputs.pull-request-number }} + id: create_branch + uses: peterjgrainger/action-create-branch@v2.2.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + branch: 'dev' + + # Make changes to pull request here -uses: peterjgrainger/action-create-branch@v2.2.0 -env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -with: - branch: 'dev' - sha: '${{ github.event.pull_request.head.sha }}' + - name: Create Pull Request + uses: peter-evans/create-pull-request@v4 From 1fb212027e25a52bcae5828441d5155b3f921742 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:38:06 -0400 Subject: [PATCH 155/329] Update release_action.yml --- .github/workflows/release_action.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index d2248acc..70d4ae74 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -7,22 +7,21 @@ jobs: new_release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - - + - uses: actions/checkout@v3 - name: Create new dev branch - if: ${{ steps.cpr.outputs.pull-request-number }} id: create_branch uses: peterjgrainger/action-create-branch@v2.2.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: branch: 'dev' - - - # Make changes to pull request here - - name: Create Pull Request + if: ${{ steps.create_branch.outputs.created }} + id: cpr uses: peter-evans/create-pull-request@v4 + base: newdev + branch: dev + delete-branch: true + title: Development PR + labels: ignore-for-release + draft: true From 00f83434738566ffb8262c33416f066da4e360c3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:44:05 -0400 Subject: [PATCH 156/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 70d4ae74..9c4516f6 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -1,6 +1,6 @@ name: Create new Branch and Release on: - workflow_dispatch: + workflow_dispatch release: types: [released] jobs: From a9dc9244422a696fae963ac4c4ac1d35c15faf2d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:45:55 -0400 Subject: [PATCH 157/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 9c4516f6..70d4ae74 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -1,6 +1,6 @@ name: Create new Branch and Release on: - workflow_dispatch + workflow_dispatch: release: types: [released] jobs: From a83e327db703c34eb5d7648123e7692906c06315 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:53:29 -0400 Subject: [PATCH 158/329] Update release_action.yml --- .github/workflows/release_action.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 70d4ae74..a5ba5c39 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -7,21 +7,22 @@ jobs: new_release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v3.0.2 - name: Create new dev branch - id: create_branch + id: action_create_branch uses: peterjgrainger/action-create-branch@v2.2.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - branch: 'dev' + branch: "dev" - name: Create Pull Request - if: ${{ steps.create_branch.outputs.created }} + if: ${{ steps.action_create_branch.outputs.created }} id: cpr uses: peter-evans/create-pull-request@v4 - base: newdev - branch: dev - delete-branch: true - title: Development PR - labels: ignore-for-release - draft: true + with: + base: newdev + branch: dev + delete-branch: true + title: Development PR + labels: ignore-for-release + draft: true From 4591bc3b3c9c72dbe86220968e19d16a7eef30bd Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 19:02:11 -0400 Subject: [PATCH 159/329] Update release_action.yml --- .github/workflows/release_action.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index a5ba5c39..2713eb71 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -8,13 +8,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 - - name: Create new dev branch - id: action_create_branch - uses: peterjgrainger/action-create-branch@v2.2.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - branch: "dev" - name: Create Pull Request if: ${{ steps.action_create_branch.outputs.created }} id: cpr From 01816f7d672c6ea04f56c66cb8795c366779d51a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 19:03:32 -0400 Subject: [PATCH 160/329] Update release_action.yml --- .github/workflows/release_action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 2713eb71..5770bdd5 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -9,7 +9,6 @@ jobs: steps: - uses: actions/checkout@v3.0.2 - name: Create Pull Request - if: ${{ steps.action_create_branch.outputs.created }} id: cpr uses: peter-evans/create-pull-request@v4 with: From 34f88f283accdd769c8d687d65c3f2503bb24b8f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 19:19:15 -0400 Subject: [PATCH 161/329] Update release_action.yml --- .github/workflows/release_action.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 5770bdd5..8ea99fbc 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -8,6 +8,26 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + # Optional. Commit message for the created commit. + # Defaults to "Apply automatic changes" + commit_message: Automated Change + + # Optional. Local and remote branch name where commit is going to be pushed + # to. Defaults to the current branch. + # You might need to set `create_branch: true` if the branch does not exist. + branch: dev + + # Optional. Options used by `git-commit`. + # See https://git-scm.com/docs/git-commit#_options + commit_options: '--allow-empty' + + # Optional. Disable dirty check and always try to create a commit and push + skip_dirty_check: true + + # Optional. Create given branch name in local and remote repository. + create_branch: true - name: Create Pull Request id: cpr uses: peter-evans/create-pull-request@v4 From b58b4570b44fb0a5b99c5a28381dc0f16f07fef1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 19:27:06 -0400 Subject: [PATCH 162/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 8ea99fbc..a5e94a7a 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -34,7 +34,7 @@ jobs: with: base: newdev branch: dev - delete-branch: true + delete-branch: false title: Development PR labels: ignore-for-release draft: true From 96dfde3592a51c4e946323bb9c66b17b3c8417bb Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 19:33:59 -0400 Subject: [PATCH 163/329] Update release_action.yml --- .github/workflows/release_action.yml | 32 +++++++++++----------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index a5e94a7a..37d2ad9c 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -8,26 +8,20 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 - - uses: stefanzweifel/git-auto-commit-action@v4 + - name: Create new dev branch + id: action_create_branch + uses: peterjgrainger/action-create-branch@v2.2.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - # Optional. Commit message for the created commit. - # Defaults to "Apply automatic changes" - commit_message: Automated Change - - # Optional. Local and remote branch name where commit is going to be pushed - # to. Defaults to the current branch. - # You might need to set `create_branch: true` if the branch does not exist. - branch: dev - - # Optional. Options used by `git-commit`. - # See https://git-scm.com/docs/git-commit#_options - commit_options: '--allow-empty' - - # Optional. Disable dirty check and always try to create a commit and push - skip_dirty_check: true - - # Optional. Create given branch name in local and remote repository. - create_branch: true + branch: "dev" + - name: Create empty commit + uses: velocibear/create-empty-commit@v1.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + email: Snuffy2@github.com + name: Snuffy2 + message: Empty commit - name: Create Pull Request id: cpr uses: peter-evans/create-pull-request@v4 From 41337e456aff7d46e6b5c1de0ba73af4958a35c4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 18:02:05 -0400 Subject: [PATCH 164/329] Actions Update --- .github/issue-branch.yml | 13 +++++++++++ .github/workflows/issue_action.yml | 13 +++++++++++ .github/workflows/mylint_action.yml | 5 ++-- .github/workflows/release_action.yml | 34 ++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 .github/issue-branch.yml create mode 100644 .github/workflows/issue_action.yml create mode 100644 .github/workflows/release_action.yml diff --git a/.github/issue-branch.yml b/.github/issue-branch.yml new file mode 100644 index 00000000..7286d39a --- /dev/null +++ b/.github/issue-branch.yml @@ -0,0 +1,13 @@ +mode: auto +silent: true +branchName: full +openDraftPR: true + +branches: + - label: bug + skip: false + prefix: bugfix/ + name: dev + prTarget: dev + - label: '*' + skip: true diff --git a/.github/workflows/issue_action.yml b/.github/workflows/issue_action.yml new file mode 100644 index 00000000..d0940e52 --- /dev/null +++ b/.github/workflows/issue_action.yml @@ -0,0 +1,13 @@ +name: Create Branch on Assigning Bug Issue +on: + issues: + types: [ assigned ] + +jobs: + create_issue_branch_job: + runs-on: ubuntu-latest + steps: + - name: Create Issue Branch + uses: robvanderleek/create-issue-branch@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 884204ca..56dba07e 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -1,8 +1,7 @@ -name: MyLint Code Updater (black, isort) +name: MyLint Code Updater (black, isort, flake8) on: [workflow_dispatch, pull_request] jobs: - linter_name: - name: MyLint Code Updater (black, isort) + mylint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml new file mode 100644 index 00000000..37d2ad9c --- /dev/null +++ b/.github/workflows/release_action.yml @@ -0,0 +1,34 @@ +name: Create new Branch and Release +on: + workflow_dispatch: + release: + types: [released] +jobs: + new_release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3.0.2 + - name: Create new dev branch + id: action_create_branch + uses: peterjgrainger/action-create-branch@v2.2.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + branch: "dev" + - name: Create empty commit + uses: velocibear/create-empty-commit@v1.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + email: Snuffy2@github.com + name: Snuffy2 + message: Empty commit + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v4 + with: + base: newdev + branch: dev + delete-branch: false + title: Development PR + labels: ignore-for-release + draft: true From 805cf4677cf908063ac77020dfbf6ab299c35859 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 19:45:24 -0400 Subject: [PATCH 165/329] Update release_action.yml --- .github/workflows/release_action.yml | 42 ++++++++++++---------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 37d2ad9c..be777709 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -8,27 +8,21 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 - - name: Create new dev branch - id: action_create_branch - uses: peterjgrainger/action-create-branch@v2.2.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - branch: "dev" - - name: Create empty commit - uses: velocibear/create-empty-commit@v1.0.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - email: Snuffy2@github.com - name: Snuffy2 - message: Empty commit - - name: Create Pull Request - id: cpr - uses: peter-evans/create-pull-request@v4 - with: - base: newdev - branch: dev - delete-branch: false - title: Development PR - labels: ignore-for-release - draft: true + - name: Create New Dev branch + run: git checkout -b dev + - name: Empty Commit + run: git commit --allow-empty -m "Empty commit" + #- name: Initialize mandatory git config + # run: | + # git config user.name "GitHub Actions" + # git config user.email noreply@github.com + #- name: Create Pull Request + # id: cpr + # uses: peter-evans/create-pull-request@v4 + # with: + # base: newdev + # branch: dev + # delete-branch: false + # title: Development PR + # labels: ignore-for-release + # draft: true From 45ecdab3ccc639283192171b0e5c04a77259db11 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 21:22:35 -0400 Subject: [PATCH 166/329] Update release_action.yml --- .github/workflows/release_action.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index be777709..0f56aa97 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -9,13 +9,13 @@ jobs: steps: - uses: actions/checkout@v3.0.2 - name: Create New Dev branch - run: git checkout -b dev + run: git checkout -b dev -track ${{ github.event.repository.default_branch }} + - name: Initialize mandatory git config + run: | + git config user.name "GitHub Actions" + git config user.email noreply@github.com - name: Empty Commit run: git commit --allow-empty -m "Empty commit" - #- name: Initialize mandatory git config - # run: | - # git config user.name "GitHub Actions" - # git config user.email noreply@github.com #- name: Create Pull Request # id: cpr # uses: peter-evans/create-pull-request@v4 From 198424079f862bd6ea7ee0a7bdd12e19139d6986 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 21:31:43 -0400 Subject: [PATCH 167/329] Update release_action.yml --- .github/workflows/release_action.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 0f56aa97..bd8dc843 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -1,15 +1,17 @@ -name: Create new Branch and Release +name: Create New Dev Branch and PR on: workflow_dispatch: release: types: [released] jobs: - new_release: + new_dev_release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 - - name: Create New Dev branch - run: git checkout -b dev -track ${{ github.event.repository.default_branch }} + - name: Create and Checkout New Dev branch + run: | + git branch dev -set-upstream-to=${{ github.event.repository.default_branch }} + git checkout dev - name: Initialize mandatory git config run: | git config user.name "GitHub Actions" From fe5be3a67e492573c16e6952b577429cbdbf91b6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 21:33:04 -0400 Subject: [PATCH 168/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index bd8dc843..ff2af9cd 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3.0.2 - name: Create and Checkout New Dev branch run: | - git branch dev -set-upstream-to=${{ github.event.repository.default_branch }} + git branch dev --set-upstream-to=${{ github.event.repository.default_branch }} git checkout dev - name: Initialize mandatory git config run: | From a9440bc11fdc6180654416896dd83f4dd1dcc874 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 21:35:54 -0400 Subject: [PATCH 169/329] Update release_action.yml --- .github/workflows/release_action.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index ff2af9cd..d4faea54 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -9,9 +9,7 @@ jobs: steps: - uses: actions/checkout@v3.0.2 - name: Create and Checkout New Dev branch - run: | - git branch dev --set-upstream-to=${{ github.event.repository.default_branch }} - git checkout dev + run: git checkout -b dev - name: Initialize mandatory git config run: | git config user.name "GitHub Actions" From a86355220f8a963a1eb4560fe52080b9f8df8a23 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 21:48:14 -0400 Subject: [PATCH 170/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index d4faea54..bf77ba61 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -16,6 +16,8 @@ jobs: git config user.email noreply@github.com - name: Empty Commit run: git commit --allow-empty -m "Empty commit" + - name: Push Commit + run: git push #- name: Create Pull Request # id: cpr # uses: peter-evans/create-pull-request@v4 From d36810c9b1c3a06370dcc6b2237b16651af30190 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 21:55:40 -0400 Subject: [PATCH 171/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index bf77ba61..13466c12 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -17,7 +17,7 @@ jobs: - name: Empty Commit run: git commit --allow-empty -m "Empty commit" - name: Push Commit - run: git push + run: git push --set-upstream origin dev #- name: Create Pull Request # id: cpr # uses: peter-evans/create-pull-request@v4 From d64c950f84a24ce099024be7a2235ce083e53c57 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 22:02:40 -0400 Subject: [PATCH 172/329] Update release_action.yml --- .github/workflows/release_action.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 13466c12..d03b1a6e 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -18,13 +18,13 @@ jobs: run: git commit --allow-empty -m "Empty commit" - name: Push Commit run: git push --set-upstream origin dev - #- name: Create Pull Request - # id: cpr - # uses: peter-evans/create-pull-request@v4 - # with: - # base: newdev - # branch: dev - # delete-branch: false - # title: Development PR - # labels: ignore-for-release - # draft: true + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v4 + with: + base: newdev + branch: dev + delete-branch: false + title: Development PR + labels: ignore-for-release + draft: true From e2dfdbf10a74402440b870899f68be7bac859411 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 22:32:34 -0400 Subject: [PATCH 173/329] Update release_action.yml --- .github/workflows/release_action.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index d03b1a6e..3d5c5fa9 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -19,12 +19,6 @@ jobs: - name: Push Commit run: git push --set-upstream origin dev - name: Create Pull Request - id: cpr - uses: peter-evans/create-pull-request@v4 - with: - base: newdev - branch: dev - delete-branch: false - title: Development PR - labels: ignore-for-release - draft: true + run: gh pr create -d -B newdev -l ignore-for-release -b "Dev PR Release" -t "Dev PR Release" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 73ab9729f725f8df3bdcb1a61dba4a2e22494c17 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 22:35:32 -0400 Subject: [PATCH 174/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 3d5c5fa9..2c90c746 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -19,6 +19,6 @@ jobs: - name: Push Commit run: git push --set-upstream origin dev - name: Create Pull Request - run: gh pr create -d -B newdev -l ignore-for-release -b "Dev PR Release" -t "Dev PR Release" + run: gh pr create -d -B ${{ github.event.repository.default_branch }} -l ignore-for-release -b "Dev PR Release" -t "Dev PR Release" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From f8129f825634d1e454a0cd08e100fc4c5fd551d4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 22:46:57 -0400 Subject: [PATCH 175/329] Update release_action.yml --- .github/workflows/release_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 2c90c746..7c31a3e9 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -12,7 +12,7 @@ jobs: run: git checkout -b dev - name: Initialize mandatory git config run: | - git config user.name "GitHub Actions" + git config user.name "My GitHub Actions" git config user.email noreply@github.com - name: Empty Commit run: git commit --allow-empty -m "Empty commit" From 6fb4f836824c2c9134a0f5c7e3e5f8d7c87f1c5d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 22:48:56 -0400 Subject: [PATCH 176/329] Update release_action.yml --- .github/workflows/release_action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index 7c31a3e9..c386a905 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -12,7 +12,7 @@ jobs: run: git checkout -b dev - name: Initialize mandatory git config run: | - git config user.name "My GitHub Actions" + git config user.name "GitHub Actions" git config user.email noreply@github.com - name: Empty Commit run: git commit --allow-empty -m "Empty commit" @@ -21,4 +21,4 @@ jobs: - name: Create Pull Request run: gh pr create -d -B ${{ github.event.repository.default_branch }} -l ignore-for-release -b "Dev PR Release" -t "Dev PR Release" env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.CPR }} From 6877aa0d53022c5681022a10f5465f29737f1d29 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 8 Sep 2022 02:49:32 +0000 Subject: [PATCH 177/329] Empty commit From 9fc5986f003c9469703a36196a6c5f8e38eefd34 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 23:12:35 -0400 Subject: [PATCH 178/329] Create branch_action --- .github/workflows/branch_action | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/branch_action diff --git a/.github/workflows/branch_action b/.github/workflows/branch_action new file mode 100644 index 00000000..39a9f9da --- /dev/null +++ b/.github/workflows/branch_action @@ -0,0 +1,13 @@ +name: Draft PR for New Branches +on: + workflow_dispatch: + create: + ref_type: branch + branches-ignore: + - dev + - newdev +jobs: + new_branch_pr: + runs-on: ubuntu-latest + steps: + - run: echo Hi From b0306ed6dadefde5c6746f5dd9ac44894facb9a8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 23:13:56 -0400 Subject: [PATCH 179/329] Rename branch_action to branch_action.yml --- .github/workflows/{branch_action => branch_action.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{branch_action => branch_action.yml} (100%) diff --git a/.github/workflows/branch_action b/.github/workflows/branch_action.yml similarity index 100% rename from .github/workflows/branch_action rename to .github/workflows/branch_action.yml From e466c33da4ad761af594ff3be40b9d82a53e18ff Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 23:18:48 -0400 Subject: [PATCH 180/329] Update branch_action.yml --- .github/workflows/branch_action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/branch_action.yml b/.github/workflows/branch_action.yml index 39a9f9da..dd29ef82 100644 --- a/.github/workflows/branch_action.yml +++ b/.github/workflows/branch_action.yml @@ -10,4 +10,5 @@ jobs: new_branch_pr: runs-on: ubuntu-latest steps: - - run: echo Hi + - uses: actions/checkout@v3.0.2 + - run: echo Branch ${GITHUB_REF##*/} From 9dd599e763f62b442389c7a2132c1a925e7b96bf Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 23:26:07 -0400 Subject: [PATCH 181/329] Update branch_action.yml --- .github/workflows/branch_action.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/branch_action.yml b/.github/workflows/branch_action.yml index dd29ef82..2cd8e9d0 100644 --- a/.github/workflows/branch_action.yml +++ b/.github/workflows/branch_action.yml @@ -12,3 +12,13 @@ jobs: steps: - uses: actions/checkout@v3.0.2 - run: echo Branch ${GITHUB_REF##*/} + - name: Create and Checkout New Dev branch + run: git checkout ${GITHUB_REF##*/} + - name: Initialize mandatory git config + run: | + git config user.name "GitHub Actions" + git config user.email noreply@github.com + - name: Create Pull Request + run: gh pr create -d -B dev -b "${GITHUB_REF##*/}" -t "${GITHUB_REF##*/}" + env: + GITHUB_TOKEN: ${{ secrets.CPR }} From 2956d3d7798716d80731c450a48c5d8013dae6d2 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 23:48:13 -0400 Subject: [PATCH 182/329] Update branch_action.yml --- .github/workflows/branch_action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/branch_action.yml b/.github/workflows/branch_action.yml index 2cd8e9d0..c17e8127 100644 --- a/.github/workflows/branch_action.yml +++ b/.github/workflows/branch_action.yml @@ -18,6 +18,8 @@ jobs: run: | git config user.name "GitHub Actions" git config user.email noreply@github.com + - run: echo "commit_count="$(git rev-list --count origin..HEAD) + - run: echo "commit_count="$(git rev-list --count origin..HEAD) >> $GITHUB_ENV - name: Create Pull Request run: gh pr create -d -B dev -b "${GITHUB_REF##*/}" -t "${GITHUB_REF##*/}" env: From 805d08ab9b6356204b52bd42a6d2fe2f3579e3bf Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 23:54:59 -0400 Subject: [PATCH 183/329] Update branch_action.yml --- .github/workflows/branch_action.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/branch_action.yml b/.github/workflows/branch_action.yml index c17e8127..282d6494 100644 --- a/.github/workflows/branch_action.yml +++ b/.github/workflows/branch_action.yml @@ -11,15 +11,18 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.0.2 - - run: echo Branch ${GITHUB_REF##*/} + - name: Show Branch Name + run: echo Branch ${GITHUB_REF##*/} - name: Create and Checkout New Dev branch run: git checkout ${GITHUB_REF##*/} - name: Initialize mandatory git config run: | git config user.name "GitHub Actions" git config user.email noreply@github.com - - run: echo "commit_count="$(git rev-list --count origin..HEAD) - - run: echo "commit_count="$(git rev-list --count origin..HEAD) >> $GITHUB_ENV + - name: Create Empty Commit + run: git commit --allow-empty -m "Empty commit" + #- run: echo "commit_count="$(git rev-list --count origin..HEAD) + #- run: echo "commit_count="$(git rev-list --count origin..HEAD) >> $GITHUB_ENV - name: Create Pull Request run: gh pr create -d -B dev -b "${GITHUB_REF##*/}" -t "${GITHUB_REF##*/}" env: From 635a169c55283815b7017da6411590d45acfa195 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 7 Sep 2022 23:56:10 -0400 Subject: [PATCH 184/329] Empty commit From 6954982973d3cae6bfdeecb1cdfa0333766caaba Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 12:58:42 -0400 Subject: [PATCH 185/329] Check initial lat/long values Even though they are stored as strings, check if the strings are numbers (floats). If not numbers, set to None. May want to change these fields to store as floats in the future --- custom_components/places/sensor.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 4895a3a3..57c8e21f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -510,6 +510,13 @@ def haversine(self, lon1, lat1, lon2, lat2): r = 6371 # Radius of earth in kilometers. Use 3956 for miles return c * r + def is_float(value): + try: + float(value) + return True + except: + return False + def do_update(self, reason): """Get the latest data and updates the states.""" @@ -544,17 +551,29 @@ def do_update(self, reason): ): now = datetime.now() old_latitude = str(self._latitude) + if (!is_float(old_latitude)): + old_latitude = None old_longitude = str(self._longitude) + if (!is_float(old_latitude)): + old_latitude = None new_latitude = str( self._hass.states.get(self._devicetracker_id).attributes.get("latitude") ) + if (!is_float(new_latitude)): + new_latitude = None new_longitude = str( self._hass.states.get(self._devicetracker_id).attributes.get( "longitude" ) ) + if (!is_float(new_longitude)): + new_longitude = None home_latitude = str(self._home_latitude) + if (!is_float(home_latitude)): + home_latitude = None home_longitude = str(self._home_longitude) + if (!is_float(home_longitude)): + home_longitude = None last_distance_m = self._distance_m last_updated = self._mtime current_location = new_latitude + "," + new_longitude From f4e5a2be6e681d00570ae93fe0461e2e65297150 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 13:16:52 -0400 Subject: [PATCH 186/329] Catch the potential issue in init as well --- custom_components/places/sensor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 57c8e21f..e9ee07fa 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -318,7 +318,11 @@ def __init__( self._state = "Initializing..." home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) + if (!is_float(home_latitude)): + home_latitude = None home_longitude = str(hass.states.get(home_zone).attributes.get("longitude")) + if (!is_float(home_longitude)): + home_longitude = None self._entity_picture = ( hass.states.get(devicetracker_id).attributes.get("entity_picture") if hass.states.get(devicetracker_id) From 1000b53aee72a463fcc981c34362434ad9be9f4b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 13:34:45 -0400 Subject: [PATCH 187/329] Update sensor.py --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e9ee07fa..1fb554df 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -318,10 +318,10 @@ def __init__( self._state = "Initializing..." home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) - if (!is_float(home_latitude)): + if (!self.is_float(home_latitude)): home_latitude = None home_longitude = str(hass.states.get(home_zone).attributes.get("longitude")) - if (!is_float(home_longitude)): + if (!self.is_float(home_longitude)): home_longitude = None self._entity_picture = ( hass.states.get(devicetracker_id).attributes.get("entity_picture") From f0757ed3dc7abb62962ac1125776757c0bfcc5d1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 13:39:19 -0400 Subject: [PATCH 188/329] Fix function calls --- custom_components/places/sensor.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 1fb554df..da2ca2a9 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -514,7 +514,7 @@ def haversine(self, lon1, lat1, lon2, lat2): r = 6371 # Radius of earth in kilometers. Use 3956 for miles return c * r - def is_float(value): + def is_float(self,value): try: float(value) return True @@ -555,28 +555,28 @@ def do_update(self, reason): ): now = datetime.now() old_latitude = str(self._latitude) - if (!is_float(old_latitude)): + if (!self.is_float(old_latitude)): old_latitude = None old_longitude = str(self._longitude) - if (!is_float(old_latitude)): + if (!self.is_float(old_latitude)): old_latitude = None new_latitude = str( self._hass.states.get(self._devicetracker_id).attributes.get("latitude") ) - if (!is_float(new_latitude)): + if (!self.is_float(new_latitude)): new_latitude = None new_longitude = str( self._hass.states.get(self._devicetracker_id).attributes.get( "longitude" ) ) - if (!is_float(new_longitude)): + if (!self.is_float(new_longitude)): new_longitude = None home_latitude = str(self._home_latitude) - if (!is_float(home_latitude)): + if (!self.is_float(home_latitude)): home_latitude = None home_longitude = str(self._home_longitude) - if (!is_float(home_longitude)): + if (!self.is_float(home_longitude)): home_longitude = None last_distance_m = self._distance_m last_updated = self._mtime From be1c7be76cd915e123fcb2360d94d0d4a9fe0834 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 13:45:11 -0400 Subject: [PATCH 189/329] Fix my incorrect way of saying not --- custom_components/places/sensor.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index da2ca2a9..3c8e34f1 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -318,10 +318,10 @@ def __init__( self._state = "Initializing..." home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) - if (!self.is_float(home_latitude)): + if (not self.is_float(home_latitude)): home_latitude = None home_longitude = str(hass.states.get(home_zone).attributes.get("longitude")) - if (!self.is_float(home_longitude)): + if (not self.is_float(home_longitude)): home_longitude = None self._entity_picture = ( hass.states.get(devicetracker_id).attributes.get("entity_picture") @@ -555,28 +555,28 @@ def do_update(self, reason): ): now = datetime.now() old_latitude = str(self._latitude) - if (!self.is_float(old_latitude)): + if (not self.is_float(old_latitude)): old_latitude = None old_longitude = str(self._longitude) - if (!self.is_float(old_latitude)): + if (not self.is_float(old_latitude)): old_latitude = None new_latitude = str( self._hass.states.get(self._devicetracker_id).attributes.get("latitude") ) - if (!self.is_float(new_latitude)): + if (not self.is_float(new_latitude)): new_latitude = None new_longitude = str( self._hass.states.get(self._devicetracker_id).attributes.get( "longitude" ) ) - if (!self.is_float(new_longitude)): + if (not self.is_float(new_longitude)): new_longitude = None home_latitude = str(self._home_latitude) - if (!self.is_float(home_latitude)): + if (not self.is_float(home_latitude)): home_latitude = None home_longitude = str(self._home_longitude) - if (!self.is_float(home_longitude)): + if (not self.is_float(home_longitude)): home_longitude = None last_distance_m = self._distance_m last_updated = self._mtime From 672d2079478486ea2b35004f7a0b32634a24f418 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 13:46:07 -0400 Subject: [PATCH 190/329] :art: Format Python code with isort & Black Code Formatter (#90) --- custom_components/places/sensor.py | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 3c8e34f1..5f24cb78 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -318,10 +318,10 @@ def __init__( self._state = "Initializing..." home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) - if (not self.is_float(home_latitude)): + if not self.is_float(home_latitude): home_latitude = None home_longitude = str(hass.states.get(home_zone).attributes.get("longitude")) - if (not self.is_float(home_longitude)): + if not self.is_float(home_longitude): home_longitude = None self._entity_picture = ( hass.states.get(devicetracker_id).attributes.get("entity_picture") @@ -514,12 +514,12 @@ def haversine(self, lon1, lat1, lon2, lat2): r = 6371 # Radius of earth in kilometers. Use 3956 for miles return c * r - def is_float(self,value): - try: - float(value) - return True - except: - return False + def is_float(self, value): + try: + float(value) + return True + except: + return False def do_update(self, reason): """Get the latest data and updates the states.""" @@ -555,29 +555,29 @@ def do_update(self, reason): ): now = datetime.now() old_latitude = str(self._latitude) - if (not self.is_float(old_latitude)): - old_latitude = None + if not self.is_float(old_latitude): + old_latitude = None old_longitude = str(self._longitude) - if (not self.is_float(old_latitude)): - old_latitude = None + if not self.is_float(old_latitude): + old_latitude = None new_latitude = str( self._hass.states.get(self._devicetracker_id).attributes.get("latitude") ) - if (not self.is_float(new_latitude)): - new_latitude = None + if not self.is_float(new_latitude): + new_latitude = None new_longitude = str( self._hass.states.get(self._devicetracker_id).attributes.get( "longitude" ) ) - if (not self.is_float(new_longitude)): - new_longitude = None + if not self.is_float(new_longitude): + new_longitude = None home_latitude = str(self._home_latitude) - if (not self.is_float(home_latitude)): - home_latitude = None + if not self.is_float(home_latitude): + home_latitude = None home_longitude = str(self._home_longitude) - if (not self.is_float(home_longitude)): - home_longitude = None + if not self.is_float(home_longitude): + home_longitude = None last_distance_m = self._distance_m last_updated = self._mtime current_location = new_latitude + "," + new_longitude From 19888660721e4f246a829bb00acdef5826c5587c Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 13:51:02 -0400 Subject: [PATCH 191/329] Specify except type --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5f24cb78..5e69030f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -518,7 +518,7 @@ def is_float(self, value): try: float(value) return True - except: + except ValueError: return False def do_update(self, reason): From c9034bffecd98bcc9366b5810465c27a60056d08 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 8 Sep 2022 13:54:05 -0400 Subject: [PATCH 192/329] Update mylint_action.yml --- .github/workflows/mylint_action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mylint_action.yml b/.github/workflows/mylint_action.yml index 56dba07e..c72403a5 100644 --- a/.github/workflows/mylint_action.yml +++ b/.github/workflows/mylint_action.yml @@ -52,7 +52,7 @@ jobs: PULL_REQUEST: "${{ steps.cpr.outputs.pull-request-number }}" MERGE_LABELS: "automerge" MERGE_METHOD: "squash" - MERGE_REMOVE_LABELS: "black,isort" + MERGE_REMOVE_LABELS: "automerge" MERGE_DELETE_BRANCH: "true" MERGE_ERROR_FAIL: "true" From de6f7b759de8446218ecb887786967e8a50fad24 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 17:58:54 -0400 Subject: [PATCH 193/329] Create empty_commit.yaml --- .github/workflows/empty_commit.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/empty_commit.yaml diff --git a/.github/workflows/empty_commit.yaml b/.github/workflows/empty_commit.yaml new file mode 100644 index 00000000..a83fe0ed --- /dev/null +++ b/.github/workflows/empty_commit.yaml @@ -0,0 +1,18 @@ +name: Create Empty Commit +on: + workflow_dispatch: +jobs: + create_empty_commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3.0.2 + - name: Show Branch Name + run: echo Branch ${GITHUB_REF##*/} + - name: Create and Checkout New Dev branch + run: git checkout ${GITHUB_REF##*/} + - name: Initialize mandatory git config + run: | + git config user.name "GitHub Actions" + git config user.email noreply@github.com + - name: Create Empty Commit + run: git commit --allow-empty -m "Empty commit" From d7e7b695a420243a5176f699cefa02b714ed7770 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 17:59:52 -0400 Subject: [PATCH 194/329] Update branch_action.yml --- .github/workflows/branch_action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/branch_action.yml b/.github/workflows/branch_action.yml index 282d6494..2a4e2c95 100644 --- a/.github/workflows/branch_action.yml +++ b/.github/workflows/branch_action.yml @@ -24,6 +24,7 @@ jobs: #- run: echo "commit_count="$(git rev-list --count origin..HEAD) #- run: echo "commit_count="$(git rev-list --count origin..HEAD) >> $GITHUB_ENV - name: Create Pull Request - run: gh pr create -d -B dev -b "${GITHUB_REF##*/}" -t "${GITHUB_REF##*/}" + run: gh pr create -d -B dev -b "${GITHUB_REF##*/}" -t "${GITHUB_REF##*/}" --head "${GITHUB_REF##*/}" env: GITHUB_TOKEN: ${{ secrets.CPR }} + GH_TOKEN: ${{ secrets.CPR }} From e8462989ff462ff62404b80703bb842300d92594 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:01:44 -0400 Subject: [PATCH 195/329] Update release_action.yml --- .github/workflows/release_action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release_action.yml b/.github/workflows/release_action.yml index c386a905..dc4e2023 100644 --- a/.github/workflows/release_action.yml +++ b/.github/workflows/release_action.yml @@ -22,3 +22,6 @@ jobs: run: gh pr create -d -B ${{ github.event.repository.default_branch }} -l ignore-for-release -b "Dev PR Release" -t "Dev PR Release" env: GITHUB_TOKEN: ${{ secrets.CPR }} + GH_TOKEN: ${{ secrets.CPR }} + + From 93ee8ff5266290e5f60d3893d7d6f754f63d37a5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:10:20 -0400 Subject: [PATCH 196/329] Create empty_commit.yaml --- .github/workflows/empty_commit.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/empty_commit.yaml diff --git a/.github/workflows/empty_commit.yaml b/.github/workflows/empty_commit.yaml new file mode 100644 index 00000000..a83fe0ed --- /dev/null +++ b/.github/workflows/empty_commit.yaml @@ -0,0 +1,18 @@ +name: Create Empty Commit +on: + workflow_dispatch: +jobs: + create_empty_commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3.0.2 + - name: Show Branch Name + run: echo Branch ${GITHUB_REF##*/} + - name: Create and Checkout New Dev branch + run: git checkout ${GITHUB_REF##*/} + - name: Initialize mandatory git config + run: | + git config user.name "GitHub Actions" + git config user.email noreply@github.com + - name: Create Empty Commit + run: git commit --allow-empty -m "Empty commit" From 2f12e2106fb4f2bf63ad4b2276be4c70d2edb8d6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:10:44 -0400 Subject: [PATCH 197/329] Create empty_commit.yaml --- .github/workflows/empty_commit.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/empty_commit.yaml diff --git a/.github/workflows/empty_commit.yaml b/.github/workflows/empty_commit.yaml new file mode 100644 index 00000000..a83fe0ed --- /dev/null +++ b/.github/workflows/empty_commit.yaml @@ -0,0 +1,18 @@ +name: Create Empty Commit +on: + workflow_dispatch: +jobs: + create_empty_commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3.0.2 + - name: Show Branch Name + run: echo Branch ${GITHUB_REF##*/} + - name: Create and Checkout New Dev branch + run: git checkout ${GITHUB_REF##*/} + - name: Initialize mandatory git config + run: | + git config user.name "GitHub Actions" + git config user.email noreply@github.com + - name: Create Empty Commit + run: git commit --allow-empty -m "Empty commit" From 20f13beb804337f8d30274af1b6ca07780aebe85 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:27:40 -0400 Subject: [PATCH 198/329] Create config_flow --- custom_components/places/config_flow.py | 203 ++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 custom_components/places/config_flow.py diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py new file mode 100644 index 00000000..6c0b1f19 --- /dev/null +++ b/custom_components/places/config_flow.py @@ -0,0 +1,203 @@ +from copy import deepcopy +import logging +from typing import Any, Dict, Optional + +from gidgethub import BadRequest +from gidgethub.aiohttp import GitHubAPI +from homeassistant import config_entries, core +from homeassistant.const import CONF_ACCESS_TOKEN, CONF_NAME, CONF_PATH, CONF_URL +from homeassistant.core import callback +from homeassistant.helpers.aiohttp_client import async_get_clientsession +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entity_registry import ( + async_entries_for_config_entry, + async_get_registry, +) +import voluptuous as vol + +from .const import CONF_REPOS, DOMAIN + +_LOGGER = logging.getLogger(__name__) + +AUTH_SCHEMA = vol.Schema( + {vol.Required(CONF_ACCESS_TOKEN): cv.string, vol.Optional(CONF_URL): cv.string} +) +REPO_SCHEMA = vol.Schema( + { + vol.Required(CONF_PATH): cv.string, + vol.Optional(CONF_NAME): cv.string, + vol.Optional("add_another"): cv.boolean, + } +) + +OPTIONS_SHCEMA = vol.Schema({vol.Optional(CONF_NAME, default="foo"): cv.string}) + + +async def validate_path(path: str, access_token: str, hass: core.HassJob) -> None: + """Validates a GitHub repo path. + + Raises a ValueError if the path is invalid. + """ + if len(path.split("/")) != 2: + raise ValueError + session = async_get_clientsession(hass) + gh = GitHubAPI(session, "requester", oauth_token=access_token) + try: + await gh.getitem(f"repos/{path}") + except BadRequest: + raise ValueError + + +async def validate_auth(access_token: str, hass: core.HomeAssistant) -> None: + """Validates a GitHub access token. + + Raises a ValueError if the auth token is invalid. + """ + session = async_get_clientsession(hass) + gh = GitHubAPI(session, "requester", oauth_token=access_token) + try: + await gh.getitem("repos/home-assistant/core") + except BadRequest: + raise ValueError + + +class GithubCustomConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): + """Github Custom config flow.""" + + data: Optional[Dict[str, Any]] + + async def async_step_user(self, user_input: Optional[Dict[str, Any]] = None): + """Invoked when a user initiates a flow via the user interface.""" + errors: Dict[str, str] = {} + if user_input is not None: + try: + await validate_auth(user_input[CONF_ACCESS_TOKEN], self.hass) + except ValueError: + errors["base"] = "auth" + if not errors: + # Input is valid, set data. + self.data = user_input + self.data[CONF_REPOS] = [] + # Return the form of the next step. + return await self.async_step_repo() + + return self.async_show_form( + step_id="user", data_schema=AUTH_SCHEMA, errors=errors + ) + + async def async_step_repo(self, user_input: Optional[Dict[str, Any]] = None): + """Second step in config flow to add a repo to watch.""" + errors: Dict[str, str] = {} + if user_input is not None: + # Validate the path. + try: + await validate_path( + user_input[CONF_PATH], self.data[CONF_ACCESS_TOKEN], self.hass + ) + except ValueError: + errors["base"] = "invalid_path" + + if not errors: + # Input is valid, set data. + self.data[CONF_REPOS].append( + { + "path": user_input[CONF_PATH], + "name": user_input.get(CONF_NAME, user_input[CONF_PATH]), + } + ) + # If user ticked the box show this form again so they can add an + # additional repo. + if user_input.get("add_another", False): + return await self.async_step_repo() + + # User is done adding repos, create the config entry. + return self.async_create_entry(title="GitHub Custom", data=self.data) + + return self.async_show_form( + step_id="repo", data_schema=REPO_SCHEMA, errors=errors + ) + + @staticmethod + @callback + def async_get_options_flow(config_entry): + """Get the options flow for this handler.""" + return OptionsFlowHandler(config_entry) + + +class OptionsFlowHandler(config_entries.OptionsFlow): + """Handles options flow for the component.""" + + def __init__(self, config_entry: config_entries.ConfigEntry) -> None: + self.config_entry = config_entry + + async def async_step_init( + self, user_input: Dict[str, Any] = None + ) -> Dict[str, Any]: + """Manage the options for the custom component.""" + errors: Dict[str, str] = {} + # Grab all configured repos from the entity registry so we can populate the + # multi-select dropdown that will allow a user to remove a repo. + entity_registry = await async_get_registry(self.hass) + entries = async_entries_for_config_entry( + entity_registry, self.config_entry.entry_id + ) + # Default value for our multi-select. + all_repos = {e.entity_id: e.original_name for e in entries} + repo_map = {e.entity_id: e for e in entries} + + if user_input is not None: + updated_repos = deepcopy(self.config_entry.data[CONF_REPOS]) + + # Remove any unchecked repos. + removed_entities = [ + entity_id + for entity_id in repo_map.keys() + if entity_id not in user_input["repos"] + ] + for entity_id in removed_entities: + # Unregister from HA + entity_registry.async_remove(entity_id) + # Remove from our configured repos. + entry = repo_map[entity_id] + entry_path = entry.unique_id + updated_repos = [e for e in updated_repos if e["path"] != entry_path] + + if user_input.get(CONF_PATH): + # Validate the path. + access_token = self.hass.data[DOMAIN][self.config_entry.entry_id][ + CONF_ACCESS_TOKEN + ] + try: + await validate_path(user_input[CONF_PATH], access_token, self.hass) + except ValueError: + errors["base"] = "invalid_path" + + if not errors: + # Add the new repo. + updated_repos.append( + { + "path": user_input[CONF_PATH], + "name": user_input.get(CONF_NAME, user_input[CONF_PATH]), + } + ) + + if not errors: + # Value of data will be set on the options property of our config_entry + # instance. + return self.async_create_entry( + title="", + data={CONF_REPOS: updated_repos}, + ) + + options_schema = vol.Schema( + { + vol.Optional("repos", default=list(all_repos.keys())): cv.multi_select( + all_repos + ), + vol.Optional(CONF_PATH): cv.string, + vol.Optional(CONF_NAME): cv.string, + } + ) + return self.async_show_form( + step_id="init", data_schema=options_schema, errors=errors + ) From 5ddc544fda43f45692f2d001cbc3becbac8d4def Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:29:38 -0400 Subject: [PATCH 199/329] :art: Format Python code with isort & Black Code Formatter (#95) --- custom_components/places/config_flow.py | 27 +++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 6c0b1f19..3a338a89 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -1,21 +1,26 @@ -from copy import deepcopy import logging -from typing import Any, Dict, Optional +from copy import deepcopy +from typing import Any +from typing import Dict +from typing import Optional +import homeassistant.helpers.config_validation as cv +import voluptuous as vol from gidgethub import BadRequest from gidgethub.aiohttp import GitHubAPI -from homeassistant import config_entries, core -from homeassistant.const import CONF_ACCESS_TOKEN, CONF_NAME, CONF_PATH, CONF_URL +from homeassistant import config_entries +from homeassistant import core +from homeassistant.const import CONF_ACCESS_TOKEN +from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_PATH +from homeassistant.const import CONF_URL from homeassistant.core import callback from homeassistant.helpers.aiohttp_client import async_get_clientsession -import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.entity_registry import ( - async_entries_for_config_entry, - async_get_registry, -) -import voluptuous as vol +from homeassistant.helpers.entity_registry import async_entries_for_config_entry +from homeassistant.helpers.entity_registry import async_get_registry -from .const import CONF_REPOS, DOMAIN +from .const import CONF_REPOS +from .const import DOMAIN _LOGGER = logging.getLogger(__name__) From b2a74499fd001e7594846e28fb21c1babb531916 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:33:16 -0400 Subject: [PATCH 200/329] Initial init and manifest changes --- custom_components/places/__init__.py | 60 ++++++++++++++++++++++++++ custom_components/places/manifest.json | 5 ++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 8b137891..7b8881ca 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -1 +1,61 @@ +"""GitHub Custom Component.""" +import asyncio +import logging + +from homeassistant import config_entries, core + +from .const import DOMAIN + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: core.HomeAssistant, entry: config_entries.ConfigEntry +) -> bool: + """Set up platform from a ConfigEntry.""" + hass.data.setdefault(DOMAIN, {}) + hass_data = dict(entry.data) + # Registers update listener to update config entry when options are updated. + unsub_options_update_listener = entry.add_update_listener(options_update_listener) + # Store a reference to the unsubscribe function to cleanup if an entry is unloaded. + hass_data["unsub_options_update_listener"] = unsub_options_update_listener + hass.data[DOMAIN][entry.entry_id] = hass_data + + # Forward the setup to the sensor platform. + hass.async_create_task( + hass.config_entries.async_forward_entry_setup(entry, "sensor") + ) + return True + + +async def options_update_listener( + hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry +): + """Handle options update.""" + await hass.config_entries.async_reload(config_entry.entry_id) + + +async def async_unload_entry( + hass: core.HomeAssistant, entry: config_entries.ConfigEntry +) -> bool: + """Unload a config entry.""" + unload_ok = all( + await asyncio.gather( + *[hass.config_entries.async_forward_entry_unload(entry, "sensor")] + ) + ) + # Remove options_update_listener. + hass.data[DOMAIN][entry.entry_id]["unsub_options_update_listener"]() + + # Remove config entry from domain. + if unload_ok: + hass.data[DOMAIN].pop(entry.entry_id) + + return unload_ok + + +async def async_setup(hass: core.HomeAssistant, config: dict) -> bool: + """Set up the GitHub Custom component from yaml configuration.""" + hass.data.setdefault(DOMAIN, {}) + return True diff --git a/custom_components/places/manifest.json b/custom_components/places/manifest.json index 39914183..df434590 100644 --- a/custom_components/places/manifest.json +++ b/custom_components/places/manifest.json @@ -1,11 +1,12 @@ { "domain": "places", "name": "Places", - "version":"1", + "version":"2", + "config_flow": true, "documentation": "/~https://github.com/Snuffy2/places", "issue_tracker": "/~https://github.com/Snuffy2/places/issues", "dependencies": ["device_tracker"], - "codeowners": ["@tenly2000","@iantrich","@Snuffy2"], + "codeowners": ["@Snuffy2"], "requirements": [], "iot_class": "cloud_polling" } From cc57f70b61308a3a7cfb9e28a2d1d3ff6f26afaa Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:37:33 -0400 Subject: [PATCH 201/329] :art: Format Python code with isort & Black Code Formatter (#96) --- custom_components/places/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 7b8881ca..65328552 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -1,9 +1,9 @@ - """GitHub Custom Component.""" import asyncio import logging -from homeassistant import config_entries, core +from homeassistant import config_entries +from homeassistant import core from .const import DOMAIN From ce1dfac35c0d3547874be347cc9058fb66cfdbaa Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 18:48:13 -0400 Subject: [PATCH 202/329] Moving lines around --- custom_components/places/const.py | 69 ++++++++++++++++++++++++++++++ custom_components/places/sensor.py | 67 +---------------------------- 2 files changed, 70 insertions(+), 66 deletions(-) create mode 100644 custom_components/places/const.py diff --git a/custom_components/places/const.py b/custom_components/places/const.py new file mode 100644 index 00000000..08fe108d --- /dev/null +++ b/custom_components/places/const.py @@ -0,0 +1,69 @@ +# Defaults +DEFAULT_ICON = "mdi:map-marker-circle" +DEFAULT_NAME = "places" +DEFAULT_OPTION = "zone, place" +DEFAULT_HOME_ZONE = "zone.home" +DEFAULT_KEY = "no key" +DEFAULT_MAP_PROVIDER = "apple" +DEFAULT_MAP_ZOOM = "18" +DEFAULT_LANGUAGE = "default" +DEFAULT_EXTENDED_ATTR = False + +# Settings +SCAN_INTERVAL = timedelta(seconds=30) +THROTTLE_INTERVAL = timedelta(seconds=600) +DEPENDENCIES = ["zone", "device_tracker"] +TRACKABLE_DOMAINS = ["device_tracker"] + +# Config +CONF_DEVICETRACKER_ID = "devicetracker_id" +CONF_HOME_ZONE = "home_zone" +CONF_OPTIONS = "options" +CONF_MAP_PROVIDER = "map_provider" +CONF_MAP_ZOOM = "map_zoom" +CONF_LANGUAGE = "language" +CONF_EXTENDED_ATTR = "extended_attr" + +# Attributes +ATTR_OPTIONS = "options" +ATTR_STREET_NUMBER = "street_number" +ATTR_STREET = "street" +ATTR_CITY = "city" +ATTR_POSTAL_TOWN = "postal_town" +ATTR_POSTAL_CODE = "postal_code" +ATTR_REGION = "state_province" +ATTR_STATE_ABBR = "state_abbr" +ATTR_COUNTRY = "country" +ATTR_COUNTY = "county" +ATTR_FORMATTED_ADDRESS = "formatted_address" +ATTR_PLACE_TYPE = "place_type" +ATTR_PLACE_NAME = "place_name" +ATTR_PLACE_CATEGORY = "place_category" +ATTR_PLACE_NEIGHBOURHOOD = "neighbourhood" +ATTR_DEVICETRACKER_ID = "devicetracker_entityid" +ATTR_DEVICETRACKER_ZONE = "devicetracker_zone" +ATTR_DEVICETRACKER_ZONE_NAME = "devicetracker_zone_name" +ATTR_PICTURE = "entity_picture" +ATTR_LATITUDE_OLD = "previous_latitude" +ATTR_LONGITUDE_OLD = "previous_longitude" +ATTR_LATITUDE = "current_latitude" +ATTR_LONGITUDE = "current_longitude" +ATTR_MTIME = "last_changed" +ATTR_DISTANCE_KM = "distance_from_home_km" +ATTR_DISTANCE_M = "distance_from_home_m" +ATTR_HOME_ZONE = "home_zone" +ATTR_HOME_LATITUDE = "home_latitude" +ATTR_HOME_LONGITUDE = "home_longitude" +ATTR_LOCATION_CURRENT = "current_location" +ATTR_LOCATION_PREVIOUS = "previous_location" +ATTR_DIRECTION_OF_TRAVEL = "direction_of_travel" +ATTR_MAP_LINK = "map_link" +ATTR_FORMATTED_PLACE = "formatted_place" +ATTR_OSM_ID = "osm_id" +ATTR_OSM_TYPE = "osm_type" +ATTR_WIKIDATA_ID = "wikidata_id" +ATTR_OSM_DICT = "osm_dict" +ATTR_OSM_DETAILS_DICT = "osm_details_dict" +ATTR_WIKIDATA_DICT = "wikidata_dict" +ATTR_LAST_PLACE_NAME = "last_place_name" + diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5e69030f..2a2e5743 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -163,6 +163,7 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol +import .const from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME @@ -175,69 +176,6 @@ _LOGGER = logging.getLogger(__name__) -DEPENDENCIES = ["zone", "device_tracker"] - -CONF_DEVICETRACKER_ID = "devicetracker_id" -CONF_HOME_ZONE = "home_zone" -CONF_OPTIONS = "options" -CONF_MAP_PROVIDER = "map_provider" -CONF_MAP_ZOOM = "map_zoom" -CONF_LANGUAGE = "language" -CONF_EXTENDED_ATTR = "extended_attr" - -ATTR_OPTIONS = "options" -ATTR_STREET_NUMBER = "street_number" -ATTR_STREET = "street" -ATTR_CITY = "city" -ATTR_POSTAL_TOWN = "postal_town" -ATTR_POSTAL_CODE = "postal_code" -ATTR_REGION = "state_province" -ATTR_STATE_ABBR = "state_abbr" -ATTR_COUNTRY = "country" -ATTR_COUNTY = "county" -ATTR_FORMATTED_ADDRESS = "formatted_address" -ATTR_PLACE_TYPE = "place_type" -ATTR_PLACE_NAME = "place_name" -ATTR_PLACE_CATEGORY = "place_category" -ATTR_PLACE_NEIGHBOURHOOD = "neighbourhood" -ATTR_DEVICETRACKER_ID = "devicetracker_entityid" -ATTR_DEVICETRACKER_ZONE = "devicetracker_zone" -ATTR_DEVICETRACKER_ZONE_NAME = "devicetracker_zone_name" -ATTR_PICTURE = "entity_picture" -ATTR_LATITUDE_OLD = "previous_latitude" -ATTR_LONGITUDE_OLD = "previous_longitude" -ATTR_LATITUDE = "current_latitude" -ATTR_LONGITUDE = "current_longitude" -ATTR_MTIME = "last_changed" -ATTR_DISTANCE_KM = "distance_from_home_km" -ATTR_DISTANCE_M = "distance_from_home_m" -ATTR_HOME_ZONE = "home_zone" -ATTR_HOME_LATITUDE = "home_latitude" -ATTR_HOME_LONGITUDE = "home_longitude" -ATTR_LOCATION_CURRENT = "current_location" -ATTR_LOCATION_PREVIOUS = "previous_location" -ATTR_DIRECTION_OF_TRAVEL = "direction_of_travel" -ATTR_MAP_LINK = "map_link" -ATTR_FORMATTED_PLACE = "formatted_place" -ATTR_OSM_ID = "osm_id" -ATTR_OSM_TYPE = "osm_type" -ATTR_WIKIDATA_ID = "wikidata_id" -ATTR_OSM_DICT = "osm_dict" -ATTR_OSM_DETAILS_DICT = "osm_details_dict" -ATTR_WIKIDATA_DICT = "wikidata_dict" -ATTR_LAST_PLACE_NAME = "last_place_name" - -DEFAULT_NAME = "places" -DEFAULT_OPTION = "zone, place" -DEFAULT_HOME_ZONE = "zone.home" -DEFAULT_KEY = "no key" -DEFAULT_MAP_PROVIDER = "apple" -DEFAULT_MAP_ZOOM = "18" -DEFAULT_LANGUAGE = "default" -DEFAULT_EXTENDED_ATTR = False - -SCAN_INTERVAL = timedelta(seconds=30) -THROTTLE_INTERVAL = timedelta(seconds=600) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { @@ -254,9 +192,6 @@ } ) -TRACKABLE_DOMAINS = ["device_tracker"] - - def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the sensor platform.""" name = config.get(CONF_NAME) From 971d1642252a11db923f8decabe7b4137f89d199 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 19:34:24 -0400 Subject: [PATCH 203/329] Update const.py --- custom_components/places/const.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 08fe108d..339c990b 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -10,6 +10,7 @@ DEFAULT_EXTENDED_ATTR = False # Settings +DOMAIN = "places" SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) DEPENDENCIES = ["zone", "device_tracker"] From f014196ad9f382b60a65d80cf61dc496fbe9c1e4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 19:34:41 -0400 Subject: [PATCH 204/329] Update const.py --- custom_components/places/const.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 339c990b..7a23d857 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -13,7 +13,6 @@ DOMAIN = "places" SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) -DEPENDENCIES = ["zone", "device_tracker"] TRACKABLE_DOMAINS = ["device_tracker"] # Config From fdfcf32ceb5cbc5e3cb9ef44c90ef6ae8c11b5e2 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 19:40:25 -0400 Subject: [PATCH 205/329] Update sensor.py --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 2a2e5743..b1985d62 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -163,7 +163,7 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol -import .const +from .const import * from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME From 7515fd3792f20c5478467af986dd22013651cfad Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 19:41:19 -0400 Subject: [PATCH 206/329] :art: Format Python code with isort & Black Code Formatter (#98) --- custom_components/places/const.py | 1 - custom_components/places/sensor.py | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 7a23d857..ea4c9b0c 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -66,4 +66,3 @@ ATTR_OSM_DETAILS_DICT = "osm_details_dict" ATTR_WIKIDATA_DICT = "wikidata_dict" ATTR_LAST_PLACE_NAME = "last_place_name" - diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b1985d62..38d62477 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -163,7 +163,6 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol -from .const import * from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME @@ -174,6 +173,8 @@ from homeassistant.util.location import distance from requests import get +from .const import * + _LOGGER = logging.getLogger(__name__) @@ -192,6 +193,7 @@ } ) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the sensor platform.""" name = config.get(CONF_NAME) From 2d8e6455c229e955acef824165b4a9ca4dbd1e4b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 19:46:31 -0400 Subject: [PATCH 207/329] Move lines --- custom_components/places/const.py | 8 ++------ custom_components/places/sensor.py | 3 +++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 7a23d857..554eeb28 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -1,3 +1,5 @@ +DOMAIN = "places" + # Defaults DEFAULT_ICON = "mdi:map-marker-circle" DEFAULT_NAME = "places" @@ -9,12 +11,6 @@ DEFAULT_LANGUAGE = "default" DEFAULT_EXTENDED_ATTR = False -# Settings -DOMAIN = "places" -SCAN_INTERVAL = timedelta(seconds=30) -THROTTLE_INTERVAL = timedelta(seconds=600) -TRACKABLE_DOMAINS = ["device_tracker"] - # Config CONF_DEVICETRACKER_ID = "devicetracker_id" CONF_HOME_ZONE = "home_zone" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b1985d62..0784c06b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -150,6 +150,9 @@ custom_components.sensor.places: debug """ +SCAN_INTERVAL = timedelta(seconds=30) +THROTTLE_INTERVAL = timedelta(seconds=600) +TRACKABLE_DOMAINS = ["device_tracker"] import json import logging From 8e9708c912260897aeaee2addf6e0b70fabb5a73 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 19:49:13 -0400 Subject: [PATCH 208/329] Update sensor.py --- custom_components/places/sensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 221f5895..96c92c0a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -150,9 +150,6 @@ custom_components.sensor.places: debug """ -SCAN_INTERVAL = timedelta(seconds=30) -THROTTLE_INTERVAL = timedelta(seconds=600) -TRACKABLE_DOMAINS = ["device_tracker"] import json import logging @@ -178,6 +175,9 @@ from .const import * +SCAN_INTERVAL = timedelta(seconds=30) +THROTTLE_INTERVAL = timedelta(seconds=600) +TRACKABLE_DOMAINS = ["device_tracker"] _LOGGER = logging.getLogger(__name__) From 6e39d33816626de1474c11b30a7829859cc1f8f6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 20:29:37 -0400 Subject: [PATCH 209/329] Update sensor.py --- custom_components/places/sensor.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 96c92c0a..49cc9514 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -153,20 +153,13 @@ import json import logging -from datetime import datetime -from datetime import timedelta -from math import asin -from math import cos -from math import radians -from math import sin -from math import sqrt +from datetime import datetime, timedelta +from math import asin, cos, radians, sin, sqrt import homeassistant.helpers.config_validation as cv import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import CONF_API_KEY -from homeassistant.const import CONF_NAME -from homeassistant.const import CONF_SCAN_INTERVAL +from homeassistant.const import CONF_API_KEY, CONF_NAME, CONF_SCAN_INTERVAL from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import track_state_change from homeassistant.util import Throttle From aa7c883e8271968081db6c6c9582423a95569da8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 20:30:37 -0400 Subject: [PATCH 210/329] :art: Format Python code with isort & Black Code Formatter (#99) --- custom_components/places/sensor.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 49cc9514..96c92c0a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -153,13 +153,20 @@ import json import logging -from datetime import datetime, timedelta -from math import asin, cos, radians, sin, sqrt +from datetime import datetime +from datetime import timedelta +from math import asin +from math import cos +from math import radians +from math import sin +from math import sqrt import homeassistant.helpers.config_validation as cv import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import CONF_API_KEY, CONF_NAME, CONF_SCAN_INTERVAL +from homeassistant.const import CONF_API_KEY +from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import track_state_change from homeassistant.util import Throttle From 630062a500fa047e415788e22fec723d0ced75c4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 20:42:44 -0400 Subject: [PATCH 211/329] Update sensor.py --- custom_components/places/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 49cc9514..286f74ff 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -168,6 +168,7 @@ from .const import * + SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) TRACKABLE_DOMAINS = ["device_tracker"] From 531ba7b8f49d19cba20aa2c8781b3f043927618f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 20:43:50 -0400 Subject: [PATCH 212/329] Update sensor.py --- custom_components/places/sensor.py | 43 ++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5d48052a..6776e855 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -173,8 +173,47 @@ from homeassistant.util.location import distance from requests import get -from .const import * - +from .const import ATTR_OPTIONS +from .const import ATTR_STREET_NUMBER +from .const import ATTR_STREET +from .const import ATTR_CITY +from .const import ATTR_POSTAL_TOWN +from .const import ATTR_POSTAL_CODE +from .const import ATTR_REGION +from .const import ATTR_STATE_ABBR +from .const import ATTR_COUNTRY +from .const import ATTR_COUNTY +from .const import ATTR_FORMATTED_ADDRESS +from .const import ATTR_PLACE_TYPE +from .const import ATTR_PLACE_NAME +from .const import ATTR_PLACE_CATEGORY +from .const import ATTR_PLACE_NEIGHBOURHOOD +from .const import ATTR_DEVICETRACKER_ID +from .const import ATTR_DEVICETRACKER_ZONE +from .const import ATTR_DEVICETRACKER_ZONE_NAME +from .const import ATTR_PICTURE +from .const import ATTR_LATITUDE_OLD +from .const import ATTR_LONGITUDE_OLD +from .const import ATTR_LATITUDE +from .const import ATTR_LONGITUDE +from .const import ATTR_MTIME +from .const import ATTR_DISTANCE_KM +from .const import ATTR_DISTANCE_M +from .const import ATTR_HOME_ZONE +from .const import ATTR_HOME_LATITUDE +from .const import ATTR_HOME_LONGITUDE +from .const import ATTR_LOCATION_CURRENT +from .const import ATTR_LOCATION_PREVIOUS +from .const import ATTR_DIRECTION_OF_TRAVEL +from .const import ATTR_MAP_LINK +from .const import ATTR_FORMATTED_PLACE +from .const import ATTR_OSM_ID +from .const import ATTR_OSM_TYPE +from .const import ATTR_WIKIDATA_ID +from .const import ATTR_OSM_DICT +from .const import ATTR_OSM_DETAILS_DICT +from .const import ATTR_WIKIDATA_DICT +from .const import ATTR_LAST_PLACE_NAME SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) From 8ce8e61a383ae5fd3caac52b47ca42e6ae09d849 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 20:44:49 -0400 Subject: [PATCH 213/329] :art: Format Python code with isort & Black Code Formatter (#100) --- custom_components/places/sensor.py | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6776e855..da327e51 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -173,47 +173,47 @@ from homeassistant.util.location import distance from requests import get -from .const import ATTR_OPTIONS -from .const import ATTR_STREET_NUMBER -from .const import ATTR_STREET from .const import ATTR_CITY -from .const import ATTR_POSTAL_TOWN -from .const import ATTR_POSTAL_CODE -from .const import ATTR_REGION -from .const import ATTR_STATE_ABBR from .const import ATTR_COUNTRY from .const import ATTR_COUNTY -from .const import ATTR_FORMATTED_ADDRESS -from .const import ATTR_PLACE_TYPE -from .const import ATTR_PLACE_NAME -from .const import ATTR_PLACE_CATEGORY -from .const import ATTR_PLACE_NEIGHBOURHOOD from .const import ATTR_DEVICETRACKER_ID from .const import ATTR_DEVICETRACKER_ZONE from .const import ATTR_DEVICETRACKER_ZONE_NAME -from .const import ATTR_PICTURE -from .const import ATTR_LATITUDE_OLD -from .const import ATTR_LONGITUDE_OLD -from .const import ATTR_LATITUDE -from .const import ATTR_LONGITUDE -from .const import ATTR_MTIME +from .const import ATTR_DIRECTION_OF_TRAVEL from .const import ATTR_DISTANCE_KM from .const import ATTR_DISTANCE_M -from .const import ATTR_HOME_ZONE +from .const import ATTR_FORMATTED_ADDRESS +from .const import ATTR_FORMATTED_PLACE from .const import ATTR_HOME_LATITUDE from .const import ATTR_HOME_LONGITUDE +from .const import ATTR_HOME_ZONE +from .const import ATTR_LAST_PLACE_NAME +from .const import ATTR_LATITUDE +from .const import ATTR_LATITUDE_OLD from .const import ATTR_LOCATION_CURRENT from .const import ATTR_LOCATION_PREVIOUS -from .const import ATTR_DIRECTION_OF_TRAVEL +from .const import ATTR_LONGITUDE +from .const import ATTR_LONGITUDE_OLD from .const import ATTR_MAP_LINK -from .const import ATTR_FORMATTED_PLACE +from .const import ATTR_MTIME +from .const import ATTR_OPTIONS +from .const import ATTR_OSM_DETAILS_DICT +from .const import ATTR_OSM_DICT from .const import ATTR_OSM_ID from .const import ATTR_OSM_TYPE -from .const import ATTR_WIKIDATA_ID -from .const import ATTR_OSM_DICT -from .const import ATTR_OSM_DETAILS_DICT +from .const import ATTR_PICTURE +from .const import ATTR_PLACE_CATEGORY +from .const import ATTR_PLACE_NAME +from .const import ATTR_PLACE_NEIGHBOURHOOD +from .const import ATTR_PLACE_TYPE +from .const import ATTR_POSTAL_CODE +from .const import ATTR_POSTAL_TOWN +from .const import ATTR_REGION +from .const import ATTR_STATE_ABBR +from .const import ATTR_STREET +from .const import ATTR_STREET_NUMBER from .const import ATTR_WIKIDATA_DICT -from .const import ATTR_LAST_PLACE_NAME +from .const import ATTR_WIKIDATA_ID SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) From 2bfe11366bf359fc79d6d178d3f13e38c806d769 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 20:57:25 -0400 Subject: [PATCH 214/329] Update sensor.py --- custom_components/places/sensor.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6776e855..9c03c16e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -214,6 +214,32 @@ from .const import ATTR_OSM_DETAILS_DICT from .const import ATTR_WIKIDATA_DICT from .const import ATTR_LAST_PLACE_NAME +from .const import CONF_DEVICETRACKER_ID +from .const import DEFAULT_KEY +from .const import CONF_OPTIONS +from .const import DEFAULT_OPTION +from .const import CONF_HOME_ZONE +from .const import DEFAULT_HOME_ZONE +from .const import DEFAULT_NAME +from .const import CONF_MAP_PROVIDER +from .const import DEFAULT_MAP_PROVIDER +from .const import CONF_MAP_ZOOM +from .const import DEFAULT_MAP_ZOOM +from .const import CONF_LANGUAGE +from .const import DEFAULT_LANGUAGE +from .const import CONF_EXTENDED_ATTR +from .const import DEFAULT_EXTENDED_ATTR +from .const import CONF_DEVICETRACKER_ID +from .const import CONF_OPTIONS +from .const import CONF_HOME_ZONE +from .const import CONF_MAP_PROVIDER +from .const import CONF_MAP_ZOOM +from .const import CONF_LANGUAGE +from .const import CONF_EXTENDED_ATTR +from .const import DEFAULT_LANGUAGE +from .const import DEFAULT_KEY +from .const import DEFAULT_KEY +from .const import DEFAULT_NAME SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) From eee936d2915428b58104fdc91a24eeacc1f80b64 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 20:59:22 -0400 Subject: [PATCH 215/329] :art: Format Python code with isort & Black Code Formatter (#101) --- custom_components/places/sensor.py | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 631aba6b..b5eb214b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -213,34 +213,22 @@ from .const import ATTR_STREET from .const import ATTR_STREET_NUMBER from .const import ATTR_WIKIDATA_DICT -from .const import ATTR_LAST_PLACE_NAME +from .const import ATTR_WIKIDATA_ID from .const import CONF_DEVICETRACKER_ID -from .const import DEFAULT_KEY -from .const import CONF_OPTIONS -from .const import DEFAULT_OPTION -from .const import CONF_HOME_ZONE -from .const import DEFAULT_HOME_ZONE -from .const import DEFAULT_NAME -from .const import CONF_MAP_PROVIDER -from .const import DEFAULT_MAP_PROVIDER -from .const import CONF_MAP_ZOOM -from .const import DEFAULT_MAP_ZOOM -from .const import CONF_LANGUAGE -from .const import DEFAULT_LANGUAGE from .const import CONF_EXTENDED_ATTR -from .const import DEFAULT_EXTENDED_ATTR -from .const import CONF_DEVICETRACKER_ID -from .const import CONF_OPTIONS from .const import CONF_HOME_ZONE +from .const import CONF_LANGUAGE from .const import CONF_MAP_PROVIDER from .const import CONF_MAP_ZOOM -from .const import CONF_LANGUAGE -from .const import CONF_EXTENDED_ATTR -from .const import DEFAULT_LANGUAGE -from .const import DEFAULT_KEY +from .const import CONF_OPTIONS +from .const import DEFAULT_EXTENDED_ATTR +from .const import DEFAULT_HOME_ZONE from .const import DEFAULT_KEY +from .const import DEFAULT_LANGUAGE +from .const import DEFAULT_MAP_PROVIDER +from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_NAME -from .const import ATTR_WIKIDATA_ID +from .const import DEFAULT_OPTION SCAN_INTERVAL = timedelta(seconds=30) THROTTLE_INTERVAL = timedelta(seconds=600) From 49a825dece0bd4857eac66abfdefc629f9251222 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 22:39:18 -0400 Subject: [PATCH 216/329] New starting code --- custom_components/places/__init__.py | 70 ++---- custom_components/places/config_flow.py | 285 ++++++++---------------- 2 files changed, 119 insertions(+), 236 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 65328552..bfd93ce9 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -1,61 +1,35 @@ -"""GitHub Custom Component.""" -import asyncio -import logging +from __future__ import annotations -from homeassistant import config_entries -from homeassistant import core +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from . import hub from .const import DOMAIN -_LOGGER = logging.getLogger(__name__) - - -async def async_setup_entry( - hass: core.HomeAssistant, entry: config_entries.ConfigEntry -) -> bool: - """Set up platform from a ConfigEntry.""" - hass.data.setdefault(DOMAIN, {}) - hass_data = dict(entry.data) - # Registers update listener to update config entry when options are updated. - unsub_options_update_listener = entry.add_update_listener(options_update_listener) - # Store a reference to the unsubscribe function to cleanup if an entry is unloaded. - hass_data["unsub_options_update_listener"] = unsub_options_update_listener - hass.data[DOMAIN][entry.entry_id] = hass_data - - # Forward the setup to the sensor platform. - hass.async_create_task( - hass.config_entries.async_forward_entry_setup(entry, "sensor") - ) - return True +# List of platforms to support. There should be a matching .py file for each, +# eg and +PLATFORMS: list[str] = ["sensor"] + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Set up Hello World from a config entry.""" + # Store an instance of the "connecting" class that does the work of speaking + # with your actual devices. + hass.data.setdefault(DOMAIN, {})[entry.entry_id] = hub.Hub(hass, entry.data["host"]) -async def options_update_listener( - hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry -): - """Handle options update.""" - await hass.config_entries.async_reload(config_entry.entry_id) + # This creates each HA object for each platform your device requires. + # It's done by calling the `async_setup_entry` function in each platform module. + hass.config_entries.async_setup_platforms(entry, PLATFORMS) + return True -async def async_unload_entry( - hass: core.HomeAssistant, entry: config_entries.ConfigEntry -) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - unload_ok = all( - await asyncio.gather( - *[hass.config_entries.async_forward_entry_unload(entry, "sensor")] - ) - ) - # Remove options_update_listener. - hass.data[DOMAIN][entry.entry_id]["unsub_options_update_listener"]() - - # Remove config entry from domain. + # This is called when an entry/configured device is to be removed. The class + # needs to unload itself, and remove callbacks. See the classes for further + # details + unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) if unload_ok: hass.data[DOMAIN].pop(entry.entry_id) return unload_ok - - -async def async_setup(hass: core.HomeAssistant, config: dict) -> bool: - """Set up the GitHub Custom component from yaml configuration.""" - hass.data.setdefault(DOMAIN, {}) - return True diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 3a338a89..07368b8d 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -1,208 +1,117 @@ +from __future__ import annotations + import logging -from copy import deepcopy from typing import Any -from typing import Dict -from typing import Optional -import homeassistant.helpers.config_validation as cv import voluptuous as vol -from gidgethub import BadRequest -from gidgethub.aiohttp import GitHubAPI -from homeassistant import config_entries -from homeassistant import core -from homeassistant.const import CONF_ACCESS_TOKEN -from homeassistant.const import CONF_NAME -from homeassistant.const import CONF_PATH -from homeassistant.const import CONF_URL -from homeassistant.core import callback -from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.entity_registry import async_entries_for_config_entry -from homeassistant.helpers.entity_registry import async_get_registry - -from .const import CONF_REPOS -from .const import DOMAIN - -_LOGGER = logging.getLogger(__name__) -AUTH_SCHEMA = vol.Schema( - {vol.Required(CONF_ACCESS_TOKEN): cv.string, vol.Optional(CONF_URL): cv.string} -) -REPO_SCHEMA = vol.Schema( - { - vol.Required(CONF_PATH): cv.string, - vol.Optional(CONF_NAME): cv.string, - vol.Optional("add_another"): cv.boolean, - } -) +from homeassistant import config_entries, exceptions +from homeassistant.core import HomeAssistant -OPTIONS_SHCEMA = vol.Schema({vol.Optional(CONF_NAME, default="foo"): cv.string}) +from .const import DOMAIN # pylint:disable=unused-import +from .hub import Hub +_LOGGER = logging.getLogger(__name__) -async def validate_path(path: str, access_token: str, hass: core.HassJob) -> None: - """Validates a GitHub repo path. - - Raises a ValueError if the path is invalid. - """ - if len(path.split("/")) != 2: - raise ValueError - session = async_get_clientsession(hass) - gh = GitHubAPI(session, "requester", oauth_token=access_token) - try: - await gh.getitem(f"repos/{path}") - except BadRequest: - raise ValueError +# This is the schema that used to display the UI to the user. This simple +# schema has a single required host field, but it could include a number of fields +# such as username, password etc. See other components in the HA core code for +# further examples. +# Note the input displayed to the user will be translated. See the +# translations/.json file and strings.json. See here for further information: +# https://developers.home-assistant.io/docs/config_entries_config_flow_handler/#translations +# At the time of writing I found the translations created by the scaffold didn't +# quite work as documented and always gave me the "Lokalise key references" string +# (in square brackets), rather than the actual translated value. I did not attempt to +# figure this out or look further into it. +DATA_SCHEMA = vol.Schema({("host"): str}) -async def validate_auth(access_token: str, hass: core.HomeAssistant) -> None: - """Validates a GitHub access token. +async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: + """Validate the user input allows us to connect. - Raises a ValueError if the auth token is invalid. + Data has the keys from DATA_SCHEMA with values provided by the user. """ - session = async_get_clientsession(hass) - gh = GitHubAPI(session, "requester", oauth_token=access_token) - try: - await gh.getitem("repos/home-assistant/core") - except BadRequest: - raise ValueError - - -class GithubCustomConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): - """Github Custom config flow.""" - - data: Optional[Dict[str, Any]] - - async def async_step_user(self, user_input: Optional[Dict[str, Any]] = None): - """Invoked when a user initiates a flow via the user interface.""" - errors: Dict[str, str] = {} + # Validate the data can be used to set up a connection. + + # This is a simple example to show an error in the UI for a short hostname + # The exceptions are defined at the end of this file, and are used in the + # `async_step_user` method below. + if len(data["host"]) < 3: + raise InvalidHost + + hub = Hub(hass, data["host"]) + # The dummy hub provides a `test_connection` method to ensure it's working + # as expected + result = await hub.test_connection() + if not result: + # If there is an error, raise an exception to notify HA that there was a + # problem. The UI will also show there was a problem + raise CannotConnect + + # If your PyPI package is not built with async, pass your methods + # to the executor: + # await hass.async_add_executor_job( + # your_validate_func, data["username"], data["password"] + # ) + + # If you cannot connect: + # throw CannotConnect + # If the authentication is wrong: + # InvalidAuth + + # Return info that you want to store in the config entry. + # "Title" is what is displayed to the user for this hub device + # It is stored internally in HA as part of the device config. + # See `async_step_user` below for how this is used + return {"title": data["host"]} + + +class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): + """Handle a config flow for Hello World.""" + + VERSION = 1 + # Pick one of the available connection classes in homeassistant/config_entries.py + # This tells HA if it should be asking for updates, or it'll be notified of updates + # automatically. This example uses PUSH, as the dummy hub will notify HA of + # changes. + CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH + + async def async_step_user(self, user_input=None): + """Handle the initial step.""" + # This goes through the steps to take the user through the setup process. + # Using this it is possible to update the UI and prompt for additional + # information. This example provides a single form (built from `DATA_SCHEMA`), + # and when that has some validated input, it calls `async_create_entry` to + # actually create the HA config entry. Note the "title" value is returned by + # `validate_input` above. + errors = {} if user_input is not None: try: - await validate_auth(user_input[CONF_ACCESS_TOKEN], self.hass) - except ValueError: - errors["base"] = "auth" - if not errors: - # Input is valid, set data. - self.data = user_input - self.data[CONF_REPOS] = [] - # Return the form of the next step. - return await self.async_step_repo() - + info = await validate_input(self.hass, user_input) + + return self.async_create_entry(title=info["title"], data=user_input) + except CannotConnect: + errors["base"] = "cannot_connect" + except InvalidHost: + # The error string is set here, and should be translated. + # This example does not currently cover translations, see the + # comments on `DATA_SCHEMA` for further details. + # Set the error on the `host` field, not the entire form. + errors["host"] = "cannot_connect" + except Exception: # pylint: disable=broad-except + _LOGGER.exception("Unexpected exception") + errors["base"] = "unknown" + + # If there is no user input or there were errors, show the form again, including any errors that were found with the input. return self.async_show_form( - step_id="user", data_schema=AUTH_SCHEMA, errors=errors + step_id="user", data_schema=DATA_SCHEMA, errors=errors ) - async def async_step_repo(self, user_input: Optional[Dict[str, Any]] = None): - """Second step in config flow to add a repo to watch.""" - errors: Dict[str, str] = {} - if user_input is not None: - # Validate the path. - try: - await validate_path( - user_input[CONF_PATH], self.data[CONF_ACCESS_TOKEN], self.hass - ) - except ValueError: - errors["base"] = "invalid_path" - - if not errors: - # Input is valid, set data. - self.data[CONF_REPOS].append( - { - "path": user_input[CONF_PATH], - "name": user_input.get(CONF_NAME, user_input[CONF_PATH]), - } - ) - # If user ticked the box show this form again so they can add an - # additional repo. - if user_input.get("add_another", False): - return await self.async_step_repo() - - # User is done adding repos, create the config entry. - return self.async_create_entry(title="GitHub Custom", data=self.data) - return self.async_show_form( - step_id="repo", data_schema=REPO_SCHEMA, errors=errors - ) +class CannotConnect(exceptions.HomeAssistantError): + """Error to indicate we cannot connect.""" - @staticmethod - @callback - def async_get_options_flow(config_entry): - """Get the options flow for this handler.""" - return OptionsFlowHandler(config_entry) - - -class OptionsFlowHandler(config_entries.OptionsFlow): - """Handles options flow for the component.""" - - def __init__(self, config_entry: config_entries.ConfigEntry) -> None: - self.config_entry = config_entry - - async def async_step_init( - self, user_input: Dict[str, Any] = None - ) -> Dict[str, Any]: - """Manage the options for the custom component.""" - errors: Dict[str, str] = {} - # Grab all configured repos from the entity registry so we can populate the - # multi-select dropdown that will allow a user to remove a repo. - entity_registry = await async_get_registry(self.hass) - entries = async_entries_for_config_entry( - entity_registry, self.config_entry.entry_id - ) - # Default value for our multi-select. - all_repos = {e.entity_id: e.original_name for e in entries} - repo_map = {e.entity_id: e for e in entries} - if user_input is not None: - updated_repos = deepcopy(self.config_entry.data[CONF_REPOS]) - - # Remove any unchecked repos. - removed_entities = [ - entity_id - for entity_id in repo_map.keys() - if entity_id not in user_input["repos"] - ] - for entity_id in removed_entities: - # Unregister from HA - entity_registry.async_remove(entity_id) - # Remove from our configured repos. - entry = repo_map[entity_id] - entry_path = entry.unique_id - updated_repos = [e for e in updated_repos if e["path"] != entry_path] - - if user_input.get(CONF_PATH): - # Validate the path. - access_token = self.hass.data[DOMAIN][self.config_entry.entry_id][ - CONF_ACCESS_TOKEN - ] - try: - await validate_path(user_input[CONF_PATH], access_token, self.hass) - except ValueError: - errors["base"] = "invalid_path" - - if not errors: - # Add the new repo. - updated_repos.append( - { - "path": user_input[CONF_PATH], - "name": user_input.get(CONF_NAME, user_input[CONF_PATH]), - } - ) - - if not errors: - # Value of data will be set on the options property of our config_entry - # instance. - return self.async_create_entry( - title="", - data={CONF_REPOS: updated_repos}, - ) - - options_schema = vol.Schema( - { - vol.Optional("repos", default=list(all_repos.keys())): cv.multi_select( - all_repos - ), - vol.Optional(CONF_PATH): cv.string, - vol.Optional(CONF_NAME): cv.string, - } - ) - return self.async_show_form( - step_id="init", data_schema=options_schema, errors=errors - ) +class InvalidHost(exceptions.HomeAssistantError): + """Error to indicate there is an invalid hostname.""" From f0caffaf034c9612fa8e94463b3416284282922c Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 11 Sep 2022 22:40:17 -0400 Subject: [PATCH 217/329] :art: Format Python code with isort & Black Code Formatter (#102) --- custom_components/places/config_flow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 07368b8d..c84e4304 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -4,8 +4,8 @@ from typing import Any import voluptuous as vol - -from homeassistant import config_entries, exceptions +from homeassistant import config_entries +from homeassistant import exceptions from homeassistant.core import HomeAssistant from .const import DOMAIN # pylint:disable=unused-import From 442a4d2e1a7e4a361a0aa00fe81075bf851c788f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:19:55 -0400 Subject: [PATCH 218/329] First pass at config_flow and async --- custom_components/places/config_flow.py | 55 ++++++++++++++++++------- custom_components/places/sensor.py | 29 +++++-------- 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index c84e4304..8784e2a4 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -9,14 +9,26 @@ from homeassistant.core import HomeAssistant from .const import DOMAIN # pylint:disable=unused-import -from .hub import Hub +from .const import CONF_DEVICETRACKER_ID +from .const import CONF_EXTENDED_ATTR +from .const import CONF_HOME_ZONE +from .const import CONF_LANGUAGE +from .const import CONF_MAP_PROVIDER +from .const import CONF_MAP_ZOOM +from .const import CONF_OPTIONS +from .const import DEFAULT_EXTENDED_ATTR +from .const import DEFAULT_HOME_ZONE +from .const import DEFAULT_KEY +from .const import DEFAULT_LANGUAGE +from .const import DEFAULT_MAP_PROVIDER +from .const import DEFAULT_MAP_ZOOM +from .const import DEFAULT_NAME +from .const import DEFAULT_OPTION +from .const import CONF_NAME +#from .hub import Hub _LOGGER = logging.getLogger(__name__) -# This is the schema that used to display the UI to the user. This simple -# schema has a single required host field, but it could include a number of fields -# such as username, password etc. See other components in the HA core code for -# further examples. # Note the input displayed to the user will be translated. See the # translations/.json file and strings.json. See here for further information: # https://developers.home-assistant.io/docs/config_entries_config_flow_handler/#translations @@ -24,8 +36,20 @@ # quite work as documented and always gave me the "Lokalise key references" string # (in square brackets), rather than the actual translated value. I did not attempt to # figure this out or look further into it. -DATA_SCHEMA = vol.Schema({("host"): str}) - +DATA_SCHEMA = vol.Schema( + { + vol.Required(CONF_DEVICETRACKER_ID): cv.string, + vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): cv.string, + vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): cv.string, + vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, + vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.string, + vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, + vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, + } +) async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: """Validate the user input allows us to connect. @@ -37,17 +61,17 @@ async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: # This is a simple example to show an error in the UI for a short hostname # The exceptions are defined at the end of this file, and are used in the # `async_step_user` method below. - if len(data["host"]) < 3: - raise InvalidHost + ##if len(data["host"]) < 3: + ## raise InvalidHost - hub = Hub(hass, data["host"]) + ##hub = Hub(hass, data["host"]) # The dummy hub provides a `test_connection` method to ensure it's working # as expected - result = await hub.test_connection() - if not result: + ##result = await hub.test_connection() + ##if not result: # If there is an error, raise an exception to notify HA that there was a # problem. The UI will also show there was a problem - raise CannotConnect + ##raise CannotConnect # If your PyPI package is not built with async, pass your methods # to the executor: @@ -64,18 +88,17 @@ async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: # "Title" is what is displayed to the user for this hub device # It is stored internally in HA as part of the device config. # See `async_step_user` below for how this is used - return {"title": data["host"]} + return {"title": data[CONF_NAME]} class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): - """Handle a config flow for Hello World.""" VERSION = 1 # Pick one of the available connection classes in homeassistant/config_entries.py # This tells HA if it should be asking for updates, or it'll be notified of updates # automatically. This example uses PUSH, as the dummy hub will notify HA of # changes. - CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH + ##CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH async def async_step_user(self, user_input=None): """Handle the initial step.""" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b5eb214b..c94178f8 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -252,7 +252,13 @@ ) -def setup_platform(hass, config, add_devices, discovery_info=None): +#def setup_platform(hass, config, add_devices, discovery_info=None): +async def async_setup_platform( + hass: HomeAssistantType, + config: ConfigType, + async_add_entities: Callable, + discovery_info: Optional[DiscoveryInfoType] = None, +) -> None: """Setup the sensor platform.""" name = config.get(CONF_NAME) api_key = config.get(CONF_API_KEY) @@ -264,22 +270,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): language = config.get(CONF_LANGUAGE) extended_attr = config.get(CONF_EXTENDED_ATTR) - add_devices( - [ - Places( - hass, - devicetracker_id, - name, - api_key, - options, - home_zone, - map_provider, - map_zoom, - language, - extended_attr, - ) - ] - ) + async_add_entities([Places()]) class Places(Entity): @@ -489,9 +480,9 @@ def tsc_update(self, tscarg2, tsarg3, tsarg4): self.do_update("Track State Change") @Throttle(THROTTLE_INTERVAL) - def update(self): + async def async_update(self): """Call the do_update function based on scan interval and throttle""" - self.do_update("Scan Interval") + await self.do_update("Scan Interval") def haversine(self, lon1, lat1, lon2, lat2): """ From bdd3e5dcf996b8dc402d51e6d1a2480f380f6436 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:20:42 -0400 Subject: [PATCH 219/329] :art: Format Python code with isort & Black Code Formatter (#103) --- custom_components/places/config_flow.py | 14 ++++++++------ custom_components/places/sensor.py | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 8784e2a4..75d68ac9 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -8,13 +8,13 @@ from homeassistant import exceptions from homeassistant.core import HomeAssistant -from .const import DOMAIN # pylint:disable=unused-import from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR from .const import CONF_HOME_ZONE from .const import CONF_LANGUAGE from .const import CONF_MAP_PROVIDER from .const import CONF_MAP_ZOOM +from .const import CONF_NAME from .const import CONF_OPTIONS from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE @@ -24,8 +24,9 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_NAME from .const import DEFAULT_OPTION -from .const import CONF_NAME -#from .hub import Hub +from .const import DOMAIN # pylint:disable=unused-import + +# from .hub import Hub _LOGGER = logging.getLogger(__name__) @@ -51,6 +52,7 @@ } ) + async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: """Validate the user input allows us to connect. @@ -69,9 +71,9 @@ async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: # as expected ##result = await hub.test_connection() ##if not result: - # If there is an error, raise an exception to notify HA that there was a - # problem. The UI will also show there was a problem - ##raise CannotConnect + # If there is an error, raise an exception to notify HA that there was a + # problem. The UI will also show there was a problem + ##raise CannotConnect # If your PyPI package is not built with async, pass your methods # to the executor: diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index c94178f8..ab9d02d6 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -252,7 +252,7 @@ ) -#def setup_platform(hass, config, add_devices, discovery_info=None): +# def setup_platform(hass, config, add_devices, discovery_info=None): async def async_setup_platform( hass: HomeAssistantType, config: ConfigType, From b25600529970ca7627a08c672cec53ef3e53d839 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:23:16 -0400 Subject: [PATCH 220/329] Update __init__.py --- custom_components/places/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index bfd93ce9..c9ba72e3 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -3,7 +3,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from . import hub +#from . import hub from .const import DOMAIN # List of platforms to support. There should be a matching .py file for each, @@ -12,10 +12,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Set up Hello World from a config entry.""" + """Set up from a config entry.""" # Store an instance of the "connecting" class that does the work of speaking # with your actual devices. - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = hub.Hub(hass, entry.data["host"]) + ##hass.data.setdefault(DOMAIN, {})[entry.entry_id] = hub.Hub(hass, entry.data["host"]) # This creates each HA object for each platform your device requires. # It's done by calling the `async_setup_entry` function in each platform module. From d398fe6553652a973c792b314cb218f44fae1c52 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:24:34 -0400 Subject: [PATCH 221/329] :art: Format Python code with isort & Black Code Formatter (#104) --- custom_components/places/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index c9ba72e3..7faebc04 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -3,7 +3,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -#from . import hub +# from . import hub from .const import DOMAIN # List of platforms to support. There should be a matching .py file for each, From 6552c5730dc90ee0c51a191e69dc4e89fbad18a0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:29:56 -0400 Subject: [PATCH 222/329] Fixes --- custom_components/places/config_flow.py | 6 ++++-- custom_components/places/const.py | 3 +++ custom_components/places/sensor.py | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 75d68ac9..e7fb8bf7 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -7,14 +7,16 @@ from homeassistant import config_entries from homeassistant import exceptions from homeassistant.core import HomeAssistant - +import homeassistant.helpers.config_validation as cv +from homeassistant.const import CONF_API_KEY +from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_SCAN_INTERVAL from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR from .const import CONF_HOME_ZONE from .const import CONF_LANGUAGE from .const import CONF_MAP_PROVIDER from .const import CONF_MAP_ZOOM -from .const import CONF_NAME from .const import CONF_OPTIONS from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE diff --git a/custom_components/places/const.py b/custom_components/places/const.py index c0fc4aac..2b2a5ccd 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -1,3 +1,5 @@ +from datetime import timedelta + DOMAIN = "places" # Defaults @@ -10,6 +12,7 @@ DEFAULT_MAP_ZOOM = "18" DEFAULT_LANGUAGE = "default" DEFAULT_EXTENDED_ATTR = False +SCAN_INTERVAL = timedelta(seconds=30) # Config CONF_DEVICETRACKER_ID = "devicetracker_id" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index ab9d02d6..1aabcbdc 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -230,7 +230,7 @@ from .const import DEFAULT_NAME from .const import DEFAULT_OPTION -SCAN_INTERVAL = timedelta(seconds=30) + THROTTLE_INTERVAL = timedelta(seconds=600) TRACKABLE_DOMAINS = ["device_tracker"] _LOGGER = logging.getLogger(__name__) From 47326229c5098d5dd45cada086ccba25321a3c16 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:30:51 -0400 Subject: [PATCH 223/329] :art: Format Python code with isort & Black Code Formatter (#105) --- custom_components/places/config_flow.py | 5 +++-- custom_components/places/sensor.py | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index e7fb8bf7..a2f68f53 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -3,14 +3,15 @@ import logging from typing import Any +import homeassistant.helpers.config_validation as cv import voluptuous as vol from homeassistant import config_entries from homeassistant import exceptions -from homeassistant.core import HomeAssistant -import homeassistant.helpers.config_validation as cv from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL +from homeassistant.core import HomeAssistant + from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR from .const import CONF_HOME_ZONE diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 1aabcbdc..efb92b34 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -230,7 +230,6 @@ from .const import DEFAULT_NAME from .const import DEFAULT_OPTION - THROTTLE_INTERVAL = timedelta(seconds=600) TRACKABLE_DOMAINS = ["device_tracker"] _LOGGER = logging.getLogger(__name__) From dbe22af4f6d5ed48b1dc0272f07ec970e8217554 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:40:08 -0400 Subject: [PATCH 224/329] Fix imports --- custom_components/places/config_flow.py | 2 ++ custom_components/places/sensor.py | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index a2f68f53..8c9d9025 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -27,6 +27,8 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_NAME from .const import DEFAULT_OPTION +from .const import SCAN_INTERVAL + from .const import DOMAIN # pylint:disable=unused-import # from .hub import Hub diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index efb92b34..d1e3d4a7 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -160,6 +160,7 @@ from math import radians from math import sin from math import sqrt +from typing import Any, Callable, Dict, Optional import homeassistant.helpers.config_validation as cv import voluptuous as vol @@ -229,6 +230,12 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_NAME from .const import DEFAULT_OPTION +from .const import SCAN_INTERVAL +from homeassistant.helpers.typing import ( + ConfigType, + DiscoveryInfoType, + HomeAssistantType, +) THROTTLE_INTERVAL = timedelta(seconds=600) TRACKABLE_DOMAINS = ["device_tracker"] From d3c0c5795f8967aa32863816e445d8e0cc6b11d9 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:41:07 -0400 Subject: [PATCH 225/329] :art: Format Python code with isort & Black Code Formatter (#106) --- custom_components/places/config_flow.py | 3 +-- custom_components/places/sensor.py | 13 +++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 8c9d9025..e18a30be 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -27,9 +27,8 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_NAME from .const import DEFAULT_OPTION -from .const import SCAN_INTERVAL - from .const import DOMAIN # pylint:disable=unused-import +from .const import SCAN_INTERVAL # from .hub import Hub diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index d1e3d4a7..c72864bb 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -160,7 +160,10 @@ from math import radians from math import sin from math import sqrt -from typing import Any, Callable, Dict, Optional +from typing import Any +from typing import Callable +from typing import Dict +from typing import Optional import homeassistant.helpers.config_validation as cv import voluptuous as vol @@ -170,6 +173,9 @@ from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import track_state_change +from homeassistant.helpers.typing import ConfigType +from homeassistant.helpers.typing import DiscoveryInfoType +from homeassistant.helpers.typing import HomeAssistantType from homeassistant.util import Throttle from homeassistant.util.location import distance from requests import get @@ -231,11 +237,6 @@ from .const import DEFAULT_NAME from .const import DEFAULT_OPTION from .const import SCAN_INTERVAL -from homeassistant.helpers.typing import ( - ConfigType, - DiscoveryInfoType, - HomeAssistantType, -) THROTTLE_INTERVAL = timedelta(seconds=600) TRACKABLE_DOMAINS = ["device_tracker"] From 3b1d2f5f8c30ee987e410495624f2169a53662c5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:44:43 -0400 Subject: [PATCH 226/329] Update sensor.py --- custom_components/places/sensor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index c72864bb..4cd7d078 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -160,9 +160,7 @@ from math import radians from math import sin from math import sqrt -from typing import Any from typing import Callable -from typing import Dict from typing import Optional import homeassistant.helpers.config_validation as cv From 3cde0231aaddae609c7458732ff2723254fdcaba Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:49:04 -0400 Subject: [PATCH 227/329] Update sensor.py --- custom_components/places/sensor.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 4cd7d078..5d4c7aaa 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -275,7 +275,22 @@ async def async_setup_platform( language = config.get(CONF_LANGUAGE) extended_attr = config.get(CONF_EXTENDED_ATTR) - async_add_entities([Places()]) + async_add_entities( + [ + Places( + hass, + devicetracker_id, + name, + api_key, + options, + home_zone, + map_provider, + map_zoom, + language, + extended_attr, + ) + ] + ) class Places(Entity): From c7c96c62553fd901db7f9edec1d4dee6f96847c5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 22:55:56 -0400 Subject: [PATCH 228/329] Temporary changes to test --- custom_components/places/const.py | 4 ++-- custom_components/places/manifest.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 2b2a5ccd..bf774e9f 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -1,10 +1,10 @@ from datetime import timedelta -DOMAIN = "places" +DOMAIN = "placesv2dev" # Defaults DEFAULT_ICON = "mdi:map-marker-circle" -DEFAULT_NAME = "places" +DEFAULT_NAME = "placesv2dev" DEFAULT_OPTION = "zone, place" DEFAULT_HOME_ZONE = "zone.home" DEFAULT_KEY = "no key" diff --git a/custom_components/places/manifest.json b/custom_components/places/manifest.json index df434590..32831dda 100644 --- a/custom_components/places/manifest.json +++ b/custom_components/places/manifest.json @@ -1,6 +1,6 @@ { - "domain": "places", - "name": "Places", + "domain": "placesv2dev", + "name": "Places v2-dev", "version":"2", "config_flow": true, "documentation": "/~https://github.com/Snuffy2/places", From 2c4c6cff8c5f6bc83a69d2cd551b38ee881f6193 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 23:17:45 -0400 Subject: [PATCH 229/329] Update config_flow.py --- custom_components/places/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index e18a30be..572380f2 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -51,7 +51,7 @@ vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.string, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, - vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.string, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, } ) From c2859d595e8c5e3d8b4f25c3ae6892a99b0eb485 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 23:51:06 -0400 Subject: [PATCH 230/329] Add strings.json --- custom_components/places/config_flow.py | 20 ++++++++++---------- custom_components/places/strings.json | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 custom_components/places/strings.json diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 572380f2..37cb6392 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -43,16 +43,16 @@ # figure this out or look further into it. DATA_SCHEMA = vol.Schema( { - vol.Required(CONF_DEVICETRACKER_ID): cv.string, - vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): cv.string, - vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): cv.string, - vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): cv.string, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, - vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.string, - vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, - vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.string, - vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, + vol.Required(CONF_DEVICETRACKER_ID): str, + vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): str, + vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): str, + vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): str, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, + vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): str, + vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): str, + vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): str, + #vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): bool, } ) diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json new file mode 100644 index 00000000..0ec25825 --- /dev/null +++ b/custom_components/places/strings.json @@ -0,0 +1,23 @@ +{ + "title": "Places", + "config": { + "step": { + "user": { + "title": "Setup OpenStreetMap Sensor", + "data": { + "Username": "Username", + "Password": "Password", + "Region": "myAir Region" + "devicetracker_id": "DeviceTracker ID," + "home_zone": "Home Zone", + "options": "Display Options", + "map_provider": "Map Provider", + "map_zoom": "Map Zoom", + "language": "Language", + "extended_attr": "Extended Attributes", + }, + "description": "Complete the following fields." + } + } + } +} \ No newline at end of file From d4be89968b4a4e4af254ab4d9e8b5b597086ea74 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 12 Sep 2022 23:52:05 -0400 Subject: [PATCH 231/329] :art: Format Python code with isort & Black Code Formatter (#107) --- custom_components/places/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 37cb6392..76dca8ad 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -51,7 +51,7 @@ vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): str, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): str, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): str, - #vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + # vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): bool, } ) From 982995c0bc4dd9ba3a882b764632aa6a021b4dae Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 00:05:58 -0400 Subject: [PATCH 232/329] Update strings.json --- custom_components/places/strings.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index 0ec25825..a9337b53 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -1,20 +1,18 @@ { "title": "Places", "config": { - "step": { + "step": { "user": { "title": "Setup OpenStreetMap Sensor", "data": { - "Username": "Username", - "Password": "Password", - "Region": "myAir Region" - "devicetracker_id": "DeviceTracker ID," + "name": "[%key:common::config_flow::data::name%]", + "devicetracker_id": "DeviceTracker ID", "home_zone": "Home Zone", "options": "Display Options", "map_provider": "Map Provider", "map_zoom": "Map Zoom", "language": "Language", - "extended_attr": "Extended Attributes", + "extended_attr": "Extended Attributes" }, "description": "Complete the following fields." } From e5fb1a097c67227641a50523b62c74a93c516b81 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 00:07:43 -0400 Subject: [PATCH 233/329] More tweaks --- custom_components/places/config_flow.py | 2 +- custom_components/places/strings.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 37cb6392..0cd97f6c 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -43,11 +43,11 @@ # figure this out or look further into it. DATA_SCHEMA = vol.Schema( { + vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, vol.Required(CONF_DEVICETRACKER_ID): str, vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): str, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): str, vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): str, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): str, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): str, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): str, diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index a9337b53..6d2929c9 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -11,6 +11,7 @@ "options": "Display Options", "map_provider": "Map Provider", "map_zoom": "Map Zoom", + "api_key": "[%key:common::config_flow::data::api_key%]", "language": "Language", "extended_attr": "Extended Attributes" }, From a4d3343157eb133871152e0e6f2012f92961d3b6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 07:42:40 -0400 Subject: [PATCH 234/329] Create en.json --- custom_components/places/translations/en.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 custom_components/places/translations/en.json diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/custom_components/places/translations/en.json @@ -0,0 +1 @@ + From 1b7c7787f0dee1079afcb923ba0953e0459fa753 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 08:04:04 -0400 Subject: [PATCH 235/329] Update en.json --- custom_components/places/translations/en.json | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index 8b137891..fbc45f11 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -1 +1,22 @@ - +{ + "title": "Places", + "config": { + "step": { + "user": { + "title": "Setup OpenStreetMap Sensor", + "data": { + "name": "[%key:common::config_flow::data::name%]", + "devicetracker_id": "DeviceTracker ID", + "home_zone": "Home Zone", + "options": "Display Options", + "map_provider": "Map Provider", + "map_zoom": "Map Zoom", + "api_key": "[%key:common::config_flow::data::api_key%]", + "language": "Language", + "extended_attr": "Extended Attributes" + }, + "description": "Complete the following fields." + } + } + } +} From 51af52610b70baf584583bc0ce929fb5fb1827a3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 08:06:13 -0400 Subject: [PATCH 236/329] Update en.json --- custom_components/places/translations/en.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index fbc45f11..dad5fb00 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -1,19 +1,19 @@ { "title": "Places", "config": { - "step": { + "step": { "user": { "title": "Setup OpenStreetMap Sensor", "data": { "name": "[%key:common::config_flow::data::name%]", "devicetracker_id": "DeviceTracker ID", - "home_zone": "Home Zone", - "options": "Display Options", - "map_provider": "Map Provider", - "map_zoom": "Map Zoom", - "api_key": "[%key:common::config_flow::data::api_key%]", - "language": "Language", - "extended_attr": "Extended Attributes" + "home_zone": "Home Zone", + "options": "Display Options", + "map_provider": "Map Provider", + "map_zoom": "Map Zoom", + "api_key": "[%key:common::config_flow::data::api_key%]", + "language": "Language", + "extended_attr": "Extended Attributes" }, "description": "Complete the following fields." } From 0c9e4cb17ef445b44737bcecdd7105442924eac3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 08:07:19 -0400 Subject: [PATCH 237/329] Update strings.json --- custom_components/places/strings.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index 6d2929c9..dad5fb00 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -1,22 +1,22 @@ { "title": "Places", "config": { - "step": { + "step": { "user": { "title": "Setup OpenStreetMap Sensor", "data": { "name": "[%key:common::config_flow::data::name%]", "devicetracker_id": "DeviceTracker ID", - "home_zone": "Home Zone", - "options": "Display Options", - "map_provider": "Map Provider", - "map_zoom": "Map Zoom", - "api_key": "[%key:common::config_flow::data::api_key%]", - "language": "Language", - "extended_attr": "Extended Attributes" + "home_zone": "Home Zone", + "options": "Display Options", + "map_provider": "Map Provider", + "map_zoom": "Map Zoom", + "api_key": "[%key:common::config_flow::data::api_key%]", + "language": "Language", + "extended_attr": "Extended Attributes" }, "description": "Complete the following fields." } } } -} \ No newline at end of file +} From f29aab1265e76bf80a7c53a61ecfc924cbb7a818 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 19:58:52 -0400 Subject: [PATCH 238/329] Significant refactoring --- custom_components/places/__init__.py | 22 ++- custom_components/places/config_flow.py | 20 ++- custom_components/places/const.py | 4 +- custom_components/places/sensor.py | 161 +++++++++++------- custom_components/places/strings.json | 2 +- custom_components/places/translations/en.json | 10 +- 6 files changed, 133 insertions(+), 86 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 7faebc04..ab4bfd42 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -1,21 +1,29 @@ -from __future__ import annotations - -from homeassistant.config_entries import ConfigEntry -from homeassistant.core import HomeAssistant +import asyncio +import logging +from homeassistant import config_entries, core +from .const import DOMAIN +#from __future__ import annotations +#from homeassistant.config_entries import ConfigEntry +#from homeassistant.core import HomeAssistant # from . import hub -from .const import DOMAIN + + +_LOGGER = logging.getLogger(__name__) # List of platforms to support. There should be a matching .py file for each, # eg and PLATFORMS: list[str] = ["sensor"] -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: core.HomeAssistant, entry: config_entries.ConfigEntry) -> bool: """Set up from a config entry.""" # Store an instance of the "connecting" class that does the work of speaking # with your actual devices. ##hass.data.setdefault(DOMAIN, {})[entry.entry_id] = hub.Hub(hass, entry.data["host"]) + hass.data.setdefault(DOMAIN, {}) + hass_data = dict(entry.data) + hass.data[DOMAIN][entry.entry_id] = hass_data # This creates each HA object for each platform your device requires. # It's done by calling the `async_setup_entry` function in each platform module. @@ -23,7 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: core.HomeAssistant, entry: config_entries.ConfigEntry) -> bool: """Unload a config entry.""" # This is called when an entry/configured device is to be removed. The class # needs to unload itself, and remove callbacks. See the classes for further diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 3ba1fbb4..560e28d0 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -5,12 +5,13 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol -from homeassistant import config_entries -from homeassistant import exceptions +#from homeassistant import config_entries +#from homeassistant import exceptions +from homeassistant import config_entries, core, exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL -from homeassistant.core import HomeAssistant +#from homeassistant.core import HomeAssistant from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR @@ -33,6 +34,7 @@ # from .hub import Hub _LOGGER = logging.getLogger(__name__) +MAP_PROVIDER_OPTIONS = ["apple","google","osm"] # Note the input displayed to the user will be translated. See the # translations/.json file and strings.json. See here for further information: @@ -43,21 +45,21 @@ # figure this out or look further into it. DATA_SCHEMA = vol.Schema( { - vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, + vol.Required(CONF_NAME): str, vol.Required(CONF_DEVICETRACKER_ID): str, - vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): str, + vol.Optional(CONF_API_KEY): str, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): str, vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): str, - vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): str, - vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): str, - vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): str, + vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): vol.In(MAP_PROVIDER_OPTIONS), + vol.Optional(CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM)): vol.All(vol.Coerce(int), vol.Range(min=1, max=20)), + vol.Optional(CONF_LANGUAGE): str, # vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): bool, } ) -async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: +async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any]: """Validate the user input allows us to connect. Data has the keys from DATA_SCHEMA with values provided by the user. diff --git a/custom_components/places/const.py b/custom_components/places/const.py index bf774e9f..5c784af0 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -9,8 +9,8 @@ DEFAULT_HOME_ZONE = "zone.home" DEFAULT_KEY = "no key" DEFAULT_MAP_PROVIDER = "apple" -DEFAULT_MAP_ZOOM = "18" -DEFAULT_LANGUAGE = "default" +DEFAULT_MAP_ZOOM = 18 +DEFAULT_LANGUAGE = "en" DEFAULT_EXTENDED_ATTR = False SCAN_INTERVAL = timedelta(seconds=30) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 5d4c7aaa..72e25d22 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -165,12 +165,13 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol +from homeassistant import config_entries, core from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.helpers.entity import Entity -from homeassistant.helpers.event import track_state_change +from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import DiscoveryInfoType from homeassistant.helpers.typing import HomeAssistantType @@ -235,6 +236,7 @@ from .const import DEFAULT_NAME from .const import DEFAULT_OPTION from .const import SCAN_INTERVAL +from .const import DOMAIN THROTTLE_INTERVAL = timedelta(seconds=600) TRACKABLE_DOMAINS = ["device_tracker"] @@ -249,7 +251,7 @@ vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, - vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.string, + vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.positive_int, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, @@ -258,66 +260,91 @@ # def setup_platform(hass, config, add_devices, discovery_info=None): -async def async_setup_platform( - hass: HomeAssistantType, - config: ConfigType, - async_add_entities: Callable, - discovery_info: Optional[DiscoveryInfoType] = None, +async def async_setup_entry( + hass: core.HomeAssistant, + config_entry: config_entries.ConfigEntry, + async_add_entities, ) -> None: """Setup the sensor platform.""" + #_LOGGER.debug("config_entry: " + str(config_entry)) + config = hass.data[DOMAIN][config_entry.entry_id] + unique_id = config_entry.entry_id name = config.get(CONF_NAME) - api_key = config.get(CONF_API_KEY) - devicetracker_id = config.get(CONF_DEVICETRACKER_ID) - options = config.get(CONF_OPTIONS) - home_zone = config.get(CONF_HOME_ZONE) - map_provider = config.get(CONF_MAP_PROVIDER) - map_zoom = config.get(CONF_MAP_ZOOM) - language = config.get(CONF_LANGUAGE) - extended_attr = config.get(CONF_EXTENDED_ATTR) - - async_add_entities( - [ - Places( - hass, - devicetracker_id, - name, - api_key, - options, - home_zone, - map_provider, - map_zoom, - language, - extended_attr, - ) - ] - ) + #_LOGGER.debug("config type: " + str(type(config))) + _LOGGER.debug("config: " + str(config)) + + #name = config.get(CONF_NAME) + #api_key = config.get(CONF_API_KEY) + #devicetracker_id = config.get(CONF_DEVICETRACKER_ID) + #options = config.get(CONF_OPTIONS) + #home_zone = config.get(CONF_HOME_ZONE) + #map_provider = config.get(CONF_MAP_PROVIDER) + #map_zoom = config.get(CONF_MAP_ZOOM) + #language = config.get(CONF_LANGUAGE) + #extended_attr = config.get(CONF_EXTENDED_ATTR) + + #async_add_entities( + # [ + # Places( + # hass, + # devicetracker_id, + # name, + # api_key, + # options, + # home_zone, + # map_provider, + # map_zoom, + # language, + # extended_attr, + # ) + # ] + #) + async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) class Places(Entity): """Representation of a Places Sensor.""" + #def __init__( + # self, + # hass, + # devicetracker_id, + # name, + # api_key, + # options, + # home_zone, + # map_provider, + # map_zoom, + # language, + # extended_attr, + #): def __init__( - self, - hass, - devicetracker_id, - name, - api_key, - options, - home_zone, - map_provider, - map_zoom, - language, - extended_attr, + self, hass, config, name, unique_id ): """Initialize the sensor.""" + #_LOGGER.debug("config type: " + str(type(config))) + #_LOGGER.debug("self type: " + str(type(self))) + _LOGGER.debug("New places sensor: " + str(name)) + _LOGGER.debug("(" + str(name) + ") unique_id: " + str(unique_id)) + _LOGGER.debug("(" + str(name) + ") config: " + str(config)) + #name = config.get(CONF_NAME) + devicetracker_id = config.get(CONF_DEVICETRACKER_ID) + api_key = config.setdefault(CONF_API_KEY, DEFAULT_KEY) + options = config.setdefault(CONF_OPTIONS,DEFAULT_OPTION) + home_zone = config.setdefault(CONF_HOME_ZONE,DEFAULT_HOME_ZONE) + map_provider = config.setdefault(CONF_MAP_PROVIDER,DEFAULT_MAP_PROVIDER) + map_zoom = config.setdefault(CONF_MAP_ZOOM,DEFAULT_MAP_ZOOM) + language = config.setdefault(CONF_LANGUAGE,DEFAULT_LANGUAGE) + extended_attr = config.setdefault(CONF_EXTENDED_ATTR,DEFAULT_EXTENDED_ATTR) self._hass = hass self._name = name + self._unique_id = unique_id self._api_key = api_key self._options = options.lower() self._devicetracker_id = devicetracker_id.lower() self._home_zone = home_zone.lower() self._map_provider = map_provider.lower() - self._map_zoom = map_zoom.lower() + self._map_zoom = map_zoom self._language = language.lower() self._language.replace(" ", "") self._extended_attr = extended_attr @@ -373,28 +400,38 @@ def __init__( self._osm_dict = None self._osm_details_dict = None self._wikidata_dict = None + + #_LOGGER.debug("config type: " + str(type(config))) + #_LOGGER.debug("config: " + str(config)) + #_LOGGER.debug("self type: " + str(type(self))) + #_LOGGER.debug("self: " + str(self)) # Check if devicetracker_id was specified correctly _LOGGER.info( - "(" + self._name + ") DeviceTracker Entity ID: " + devicetracker_id + "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id ) - if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: - self._devicetracker_id = devicetracker_id - track_state_change( - hass, - self._devicetracker_id, - self.tsc_update, - from_state=None, - to_state=None, - ) - _LOGGER.info("(" + self._name + ") Now subscribed to state change events") + #if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: + #self._devicetracker_id = devicetracker_id + async_track_state_change( + hass, + self._devicetracker_id, + self.tsc_update, + from_state=None, + to_state=None, + ) + _LOGGER.info("(" + self._name + ") Now subscribed to state change events") @property def name(self): """Return the name of the sensor.""" return self._name + @property + def unique_id(self): + """Return a unique ID to use for this sensor.""" + return self._unique_id + @property def state(self): """Return the state of the sensor.""" @@ -502,7 +539,7 @@ def tsc_update(self, tscarg2, tsarg3, tsarg4): @Throttle(THROTTLE_INTERVAL) async def async_update(self): """Call the do_update function based on scan interval and throttle""" - await self.do_update("Scan Interval") + await self._hass.async_add_executor_job(self.do_update("Scan Interval")) def haversine(self, lon1, lat1, lon2, lat2): """ @@ -557,7 +594,7 @@ def do_update(self, reason): if ( hasattr(self, "_devicetracker_id") - and self.hass.states.get(self._devicetracker_id) is not None + and self._hass.states.get(self._devicetracker_id) is not None ): now = datetime.now() old_latitude = str(self._latitude) @@ -642,7 +679,7 @@ def do_update(self, reason): "https://maps.apple.com/maps/?q=" + current_location + "&z=" - + self._map_zoom + + str(self._map_zoom) ) # maplink_google = 'https://www.google.com/maps/dir/?api=1&origin=' + current_location + '&destination=' + home_location + '&travelmode=driving&layer=traffic' maplink_google = ( @@ -655,7 +692,7 @@ def do_update(self, reason): + "&mlon=" + new_longitude + "#map=" - + self._map_zoom + + str(self._map_zoom) + "/" + new_latitude[:8] + "/" @@ -710,17 +747,17 @@ def do_update(self, reason): """Update if location has changed.""" - devicetracker_zone = self.hass.states.get(self._devicetracker_id).state + devicetracker_zone = self._hass.states.get(self._devicetracker_id).state _LOGGER.info( "(" + self._name + ") DeviceTracker Zone: " + devicetracker_zone ) - devicetracker_zone_id = self.hass.states.get( + devicetracker_zone_id = self._hass.states.get( self._devicetracker_id ).attributes.get("zone") if devicetracker_zone_id is not None: devicetracker_zone_id = "zone." + devicetracker_zone_id - devicetracker_zone_name_state = self.hass.states.get( + devicetracker_zone_name_state = self._hass.states.get( devicetracker_zone_id ) if devicetracker_zone_name_state is not None: diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index dad5fb00..8f5a691a 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -1,5 +1,5 @@ { - "title": "Places", + "title": "Places v2-dev", "config": { "step": { "user": { diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index dad5fb00..99702b2d 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -1,19 +1,19 @@ { - "title": "Places", + "title": "Places v2-dev", "config": { "step": { "user": { - "title": "Setup OpenStreetMap Sensor", + "title": "Setup OpenStreetMap Sensor (places)", "data": { - "name": "[%key:common::config_flow::data::name%]", + "name": "Sensor Name", "devicetracker_id": "DeviceTracker ID", "home_zone": "Home Zone", "options": "Display Options", "map_provider": "Map Provider", "map_zoom": "Map Zoom", - "api_key": "[%key:common::config_flow::data::api_key%]", + "api_key": "Email", "language": "Language", - "extended_attr": "Extended Attributes" + "extended_attr": "Enable Extended Attributes" }, "description": "Complete the following fields." } From 87033814c01ccb15766b50eaef650621ded044c0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 19:59:50 -0400 Subject: [PATCH 239/329] :art: Format Python code with isort & Black Code Formatter (#108) --- custom_components/places/__init__.py | 19 +++++-- custom_components/places/config_flow.py | 23 +++++--- custom_components/places/sensor.py | 73 ++++++++++++------------- 3 files changed, 65 insertions(+), 50 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index ab4bfd42..50894688 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -1,11 +1,14 @@ import asyncio import logging -from homeassistant import config_entries, core + +from homeassistant import config_entries +from homeassistant import core + from .const import DOMAIN -#from __future__ import annotations -#from homeassistant.config_entries import ConfigEntry -#from homeassistant.core import HomeAssistant +# from __future__ import annotations +# from homeassistant.config_entries import ConfigEntry +# from homeassistant.core import HomeAssistant # from . import hub @@ -16,7 +19,9 @@ PLATFORMS: list[str] = ["sensor"] -async def async_setup_entry(hass: core.HomeAssistant, entry: config_entries.ConfigEntry) -> bool: +async def async_setup_entry( + hass: core.HomeAssistant, entry: config_entries.ConfigEntry +) -> bool: """Set up from a config entry.""" # Store an instance of the "connecting" class that does the work of speaking # with your actual devices. @@ -31,7 +36,9 @@ async def async_setup_entry(hass: core.HomeAssistant, entry: config_entries.Conf return True -async def async_unload_entry(hass: core.HomeAssistant, entry: config_entries.ConfigEntry) -> bool: +async def async_unload_entry( + hass: core.HomeAssistant, entry: config_entries.ConfigEntry +) -> bool: """Unload a config entry.""" # This is called when an entry/configured device is to be removed. The class # needs to unload itself, and remove callbacks. See the classes for further diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 560e28d0..b22290cf 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -5,13 +5,15 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol -#from homeassistant import config_entries -#from homeassistant import exceptions -from homeassistant import config_entries, core, exceptions + +# from homeassistant import config_entries +# from homeassistant import exceptions +from homeassistant import config_entries +from homeassistant import core +from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL -#from homeassistant.core import HomeAssistant from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR @@ -31,10 +33,13 @@ from .const import DOMAIN # pylint:disable=unused-import from .const import SCAN_INTERVAL +# from homeassistant.core import HomeAssistant + + # from .hub import Hub _LOGGER = logging.getLogger(__name__) -MAP_PROVIDER_OPTIONS = ["apple","google","osm"] +MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] # Note the input displayed to the user will be translated. See the # translations/.json file and strings.json. See here for further information: @@ -50,8 +55,12 @@ vol.Optional(CONF_API_KEY): str, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): str, vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): str, - vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): vol.In(MAP_PROVIDER_OPTIONS), - vol.Optional(CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM)): vol.All(vol.Coerce(int), vol.Range(min=1, max=20)), + vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): vol.In( + MAP_PROVIDER_OPTIONS + ), + vol.Optional(CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM)): vol.All( + vol.Coerce(int), vol.Range(min=1, max=20) + ), vol.Optional(CONF_LANGUAGE): str, # vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): bool, diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 72e25d22..4eefbd5e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -165,7 +165,8 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol -from homeassistant import config_entries, core +from homeassistant import config_entries +from homeassistant import core from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME @@ -235,8 +236,8 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_NAME from .const import DEFAULT_OPTION -from .const import SCAN_INTERVAL from .const import DOMAIN +from .const import SCAN_INTERVAL THROTTLE_INTERVAL = timedelta(seconds=600) TRACKABLE_DOMAINS = ["device_tracker"] @@ -266,24 +267,24 @@ async def async_setup_entry( async_add_entities, ) -> None: """Setup the sensor platform.""" - #_LOGGER.debug("config_entry: " + str(config_entry)) + # _LOGGER.debug("config_entry: " + str(config_entry)) config = hass.data[DOMAIN][config_entry.entry_id] unique_id = config_entry.entry_id name = config.get(CONF_NAME) - #_LOGGER.debug("config type: " + str(type(config))) + # _LOGGER.debug("config type: " + str(type(config))) _LOGGER.debug("config: " + str(config)) - #name = config.get(CONF_NAME) - #api_key = config.get(CONF_API_KEY) - #devicetracker_id = config.get(CONF_DEVICETRACKER_ID) - #options = config.get(CONF_OPTIONS) - #home_zone = config.get(CONF_HOME_ZONE) - #map_provider = config.get(CONF_MAP_PROVIDER) - #map_zoom = config.get(CONF_MAP_ZOOM) - #language = config.get(CONF_LANGUAGE) - #extended_attr = config.get(CONF_EXTENDED_ATTR) - - #async_add_entities( + # name = config.get(CONF_NAME) + # api_key = config.get(CONF_API_KEY) + # devicetracker_id = config.get(CONF_DEVICETRACKER_ID) + # options = config.get(CONF_OPTIONS) + # home_zone = config.get(CONF_HOME_ZONE) + # map_provider = config.get(CONF_MAP_PROVIDER) + # map_zoom = config.get(CONF_MAP_ZOOM) + # language = config.get(CONF_LANGUAGE) + # extended_attr = config.get(CONF_EXTENDED_ATTR) + + # async_add_entities( # [ # Places( # hass, @@ -298,14 +299,14 @@ async def async_setup_entry( # extended_attr, # ) # ] - #) + # ) async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) class Places(Entity): """Representation of a Places Sensor.""" - #def __init__( + # def __init__( # self, # hass, # devicetracker_id, @@ -317,25 +318,23 @@ class Places(Entity): # map_zoom, # language, # extended_attr, - #): - def __init__( - self, hass, config, name, unique_id - ): + # ): + def __init__(self, hass, config, name, unique_id): """Initialize the sensor.""" - #_LOGGER.debug("config type: " + str(type(config))) - #_LOGGER.debug("self type: " + str(type(self))) + # _LOGGER.debug("config type: " + str(type(config))) + # _LOGGER.debug("self type: " + str(type(self))) _LOGGER.debug("New places sensor: " + str(name)) _LOGGER.debug("(" + str(name) + ") unique_id: " + str(unique_id)) _LOGGER.debug("(" + str(name) + ") config: " + str(config)) - #name = config.get(CONF_NAME) + # name = config.get(CONF_NAME) devicetracker_id = config.get(CONF_DEVICETRACKER_ID) api_key = config.setdefault(CONF_API_KEY, DEFAULT_KEY) - options = config.setdefault(CONF_OPTIONS,DEFAULT_OPTION) - home_zone = config.setdefault(CONF_HOME_ZONE,DEFAULT_HOME_ZONE) - map_provider = config.setdefault(CONF_MAP_PROVIDER,DEFAULT_MAP_PROVIDER) - map_zoom = config.setdefault(CONF_MAP_ZOOM,DEFAULT_MAP_ZOOM) - language = config.setdefault(CONF_LANGUAGE,DEFAULT_LANGUAGE) - extended_attr = config.setdefault(CONF_EXTENDED_ATTR,DEFAULT_EXTENDED_ATTR) + options = config.setdefault(CONF_OPTIONS, DEFAULT_OPTION) + home_zone = config.setdefault(CONF_HOME_ZONE, DEFAULT_HOME_ZONE) + map_provider = config.setdefault(CONF_MAP_PROVIDER, DEFAULT_MAP_PROVIDER) + map_zoom = config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM) + language = config.setdefault(CONF_LANGUAGE, DEFAULT_LANGUAGE) + extended_attr = config.setdefault(CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR) self._hass = hass self._name = name self._unique_id = unique_id @@ -400,19 +399,19 @@ def __init__( self._osm_dict = None self._osm_details_dict = None self._wikidata_dict = None - - #_LOGGER.debug("config type: " + str(type(config))) - #_LOGGER.debug("config: " + str(config)) - #_LOGGER.debug("self type: " + str(type(self))) - #_LOGGER.debug("self: " + str(self)) + + # _LOGGER.debug("config type: " + str(type(config))) + # _LOGGER.debug("config: " + str(config)) + # _LOGGER.debug("self type: " + str(type(self))) + # _LOGGER.debug("self: " + str(self)) # Check if devicetracker_id was specified correctly _LOGGER.info( "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id ) - #if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: - #self._devicetracker_id = devicetracker_id + # if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: + # self._devicetracker_id = devicetracker_id async_track_state_change( hass, self._devicetracker_id, From ed445339793d1a512dea8b19869a6b58b61881f5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 20:06:18 -0400 Subject: [PATCH 240/329] flake8 Changes --- custom_components/places/__init__.py | 1 - custom_components/places/config_flow.py | 12 ------------ custom_components/places/sensor.py | 5 ----- 3 files changed, 18 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 50894688..39a832dd 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -1,4 +1,3 @@ -import asyncio import logging from homeassistant import config_entries diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index b22290cf..4e7fe345 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -3,17 +3,13 @@ import logging from typing import Any -import homeassistant.helpers.config_validation as cv import voluptuous as vol -# from homeassistant import config_entries -# from homeassistant import exceptions from homeassistant import config_entries from homeassistant import core from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME -from homeassistant.const import CONF_SCAN_INTERVAL from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR @@ -24,19 +20,11 @@ from .const import CONF_OPTIONS from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE -from .const import DEFAULT_KEY -from .const import DEFAULT_LANGUAGE from .const import DEFAULT_MAP_PROVIDER from .const import DEFAULT_MAP_ZOOM -from .const import DEFAULT_NAME from .const import DEFAULT_OPTION from .const import DOMAIN # pylint:disable=unused-import -from .const import SCAN_INTERVAL -# from homeassistant.core import HomeAssistant - - -# from .hub import Hub _LOGGER = logging.getLogger(__name__) MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 4eefbd5e..6e473f8a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -160,8 +160,6 @@ from math import radians from math import sin from math import sqrt -from typing import Callable -from typing import Optional import homeassistant.helpers.config_validation as cv import voluptuous as vol @@ -173,9 +171,6 @@ from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change -from homeassistant.helpers.typing import ConfigType -from homeassistant.helpers.typing import DiscoveryInfoType -from homeassistant.helpers.typing import HomeAssistantType from homeassistant.util import Throttle from homeassistant.util.location import distance from requests import get From e022d44d9c04578b2e1cff68a55cc66cb4e7c051 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 20:07:06 -0400 Subject: [PATCH 241/329] :art: Format Python code with isort & Black Code Formatter (#109) --- custom_components/places/config_flow.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 4e7fe345..428fb638 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -4,7 +4,6 @@ from typing import Any import voluptuous as vol - from homeassistant import config_entries from homeassistant import core from homeassistant import exceptions @@ -25,7 +24,6 @@ from .const import DEFAULT_OPTION from .const import DOMAIN # pylint:disable=unused-import - _LOGGER = logging.getLogger(__name__) MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] From ee2b955ab85bbdb7d1a2c23079278962dac8c009 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 20:15:00 -0400 Subject: [PATCH 242/329] Optimizing code --- custom_components/places/sensor.py | 81 ++++++------------------------ 1 file changed, 14 insertions(+), 67 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6e473f8a..728ebd65 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -254,94 +254,42 @@ } ) - -# def setup_platform(hass, config, add_devices, discovery_info=None): async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, async_add_entities, ) -> None: """Setup the sensor platform.""" - # _LOGGER.debug("config_entry: " + str(config_entry)) + config = hass.data[DOMAIN][config_entry.entry_id] unique_id = config_entry.entry_id name = config.get(CONF_NAME) - # _LOGGER.debug("config type: " + str(type(config))) _LOGGER.debug("config: " + str(config)) - # name = config.get(CONF_NAME) - # api_key = config.get(CONF_API_KEY) - # devicetracker_id = config.get(CONF_DEVICETRACKER_ID) - # options = config.get(CONF_OPTIONS) - # home_zone = config.get(CONF_HOME_ZONE) - # map_provider = config.get(CONF_MAP_PROVIDER) - # map_zoom = config.get(CONF_MAP_ZOOM) - # language = config.get(CONF_LANGUAGE) - # extended_attr = config.get(CONF_EXTENDED_ATTR) - - # async_add_entities( - # [ - # Places( - # hass, - # devicetracker_id, - # name, - # api_key, - # options, - # home_zone, - # map_provider, - # map_zoom, - # language, - # extended_attr, - # ) - # ] - # ) async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) class Places(Entity): """Representation of a Places Sensor.""" - # def __init__( - # self, - # hass, - # devicetracker_id, - # name, - # api_key, - # options, - # home_zone, - # map_provider, - # map_zoom, - # language, - # extended_attr, - # ): def __init__(self, hass, config, name, unique_id): """Initialize the sensor.""" - # _LOGGER.debug("config type: " + str(type(config))) - # _LOGGER.debug("self type: " + str(type(self))) _LOGGER.debug("New places sensor: " + str(name)) _LOGGER.debug("(" + str(name) + ") unique_id: " + str(unique_id)) _LOGGER.debug("(" + str(name) + ") config: " + str(config)) - # name = config.get(CONF_NAME) - devicetracker_id = config.get(CONF_DEVICETRACKER_ID) - api_key = config.setdefault(CONF_API_KEY, DEFAULT_KEY) - options = config.setdefault(CONF_OPTIONS, DEFAULT_OPTION) - home_zone = config.setdefault(CONF_HOME_ZONE, DEFAULT_HOME_ZONE) - map_provider = config.setdefault(CONF_MAP_PROVIDER, DEFAULT_MAP_PROVIDER) - map_zoom = config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM) - language = config.setdefault(CONF_LANGUAGE, DEFAULT_LANGUAGE) - extended_attr = config.setdefault(CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR) + self._hass = hass self._name = name self._unique_id = unique_id - self._api_key = api_key - self._options = options.lower() - self._devicetracker_id = devicetracker_id.lower() - self._home_zone = home_zone.lower() - self._map_provider = map_provider.lower() - self._map_zoom = map_zoom - self._language = language.lower() + self._api_key = config.setdefault(CONF_API_KEY, DEFAULT_KEY) + self._options = config.setdefault(CONF_OPTIONS, DEFAULT_OPTION).lower() + self._devicetracker_id = config.get(CONF_DEVICETRACKER_ID).lower() + self._home_zone = config.setdefault(CONF_HOME_ZONE, DEFAULT_HOME_ZONE).lower() + self._map_provider = config.setdefault(CONF_MAP_PROVIDER, DEFAULT_MAP_PROVIDER).lower() + self._map_zoom = config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM) + self._language = config.setdefault(CONF_LANGUAGE, DEFAULT_LANGUAGE).lower() self._language.replace(" ", "") - self._extended_attr = extended_attr + self._extended_attr = config.setdefault(CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR) self._state = "Initializing..." home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) @@ -395,11 +343,6 @@ def __init__(self, hass, config, name, unique_id): self._osm_details_dict = None self._wikidata_dict = None - # _LOGGER.debug("config type: " + str(type(config))) - # _LOGGER.debug("config: " + str(config)) - # _LOGGER.debug("self type: " + str(type(self))) - # _LOGGER.debug("self: " + str(self)) - # Check if devicetracker_id was specified correctly _LOGGER.info( "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id @@ -585,6 +528,10 @@ def do_update(self, reason): "(" + self._name + ") Check if update req'd: " + self._devicetracker_id ) _LOGGER.debug("(" + self._name + ") Previous State: " + previous_state) + + _LOGGER.info( + "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id + ) if ( hasattr(self, "_devicetracker_id") From 77e5473063f977c734456c1a4c9336d26cf0f9e6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 20:15:55 -0400 Subject: [PATCH 243/329] :art: Format Python code with isort & Black Code Formatter (#110) --- custom_components/places/sensor.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 728ebd65..856d906a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -254,6 +254,7 @@ } ) + async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, @@ -285,11 +286,15 @@ def __init__(self, hass, config, name, unique_id): self._options = config.setdefault(CONF_OPTIONS, DEFAULT_OPTION).lower() self._devicetracker_id = config.get(CONF_DEVICETRACKER_ID).lower() self._home_zone = config.setdefault(CONF_HOME_ZONE, DEFAULT_HOME_ZONE).lower() - self._map_provider = config.setdefault(CONF_MAP_PROVIDER, DEFAULT_MAP_PROVIDER).lower() + self._map_provider = config.setdefault( + CONF_MAP_PROVIDER, DEFAULT_MAP_PROVIDER + ).lower() self._map_zoom = config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM) self._language = config.setdefault(CONF_LANGUAGE, DEFAULT_LANGUAGE).lower() self._language.replace(" ", "") - self._extended_attr = config.setdefault(CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR) + self._extended_attr = config.setdefault( + CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR + ) self._state = "Initializing..." home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) @@ -528,7 +533,7 @@ def do_update(self, reason): "(" + self._name + ") Check if update req'd: " + self._devicetracker_id ) _LOGGER.debug("(" + self._name + ") Previous State: " + previous_state) - + _LOGGER.info( "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id ) From 6e79c217b5a5d32b870b5834312f911a38578b4a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 20:18:10 -0400 Subject: [PATCH 244/329] flake8 fixes --- custom_components/places/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 728ebd65..dd36d2a3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -292,15 +292,15 @@ def __init__(self, hass, config, name, unique_id): self._extended_attr = config.setdefault(CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR) self._state = "Initializing..." - home_latitude = str(hass.states.get(home_zone).attributes.get("latitude")) + home_latitude = str(hass.states.get(self._home_zone).attributes.get("latitude")) if not self.is_float(home_latitude): home_latitude = None - home_longitude = str(hass.states.get(home_zone).attributes.get("longitude")) + home_longitude = str(hass.states.get(self._home_zone).attributes.get("longitude")) if not self.is_float(home_longitude): home_longitude = None self._entity_picture = ( - hass.states.get(devicetracker_id).attributes.get("entity_picture") - if hass.states.get(devicetracker_id) + hass.states.get(self._devicetracker_id).attributes.get("entity_picture") + if hass.states.get(self._devicetracker_id) else None ) self._street_number = None From 14de7237bab433574142d32cfda9e7f1e3dd42cc Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 20:19:03 -0400 Subject: [PATCH 245/329] :art: Format Python code with isort & Black Code Formatter (#111) --- custom_components/places/sensor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8d603af4..47f76ded 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -300,7 +300,9 @@ def __init__(self, hass, config, name, unique_id): home_latitude = str(hass.states.get(self._home_zone).attributes.get("latitude")) if not self.is_float(home_latitude): home_latitude = None - home_longitude = str(hass.states.get(self._home_zone).attributes.get("longitude")) + home_longitude = str( + hass.states.get(self._home_zone).attributes.get("longitude") + ) if not self.is_float(home_longitude): home_longitude = None self._entity_picture = ( From f1a3796fb4cc3aa161c5e4f8da0375a89f1c5f78 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 20:58:23 -0400 Subject: [PATCH 246/329] Update sensor.py --- custom_components/places/sensor.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 47f76ded..43cb374a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -536,9 +536,15 @@ def do_update(self, reason): ) _LOGGER.debug("(" + self._name + ") Previous State: " + previous_state) - _LOGGER.info( + _LOGGER.debug( "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id ) + _LOGGER.debug( + "(" + self._name + ") DeviceTracker Attribute: " + str(hasattr(self, "_devicetracker_id")) + ) + _LOGGER.debug( + "(" + self._name + ") DeviceTracker Entity: " + str(self._hass.states.get(self._devicetracker_id)) + ) if ( hasattr(self, "_devicetracker_id") @@ -586,6 +592,7 @@ def do_update(self, reason): "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home" + or self._devicetracker_zone.lower() == "notset" ): # Not in a Zone if self._place_name is not None and self._place_name != "-": @@ -888,7 +895,11 @@ def do_update(self, reason): if "name:" + language in osm_decoded["namedetails"]: place_name = osm_decoded["namedetails"]["name:" + language] break - if self._devicetracker_zone == "not_home" and place_name != "house": + if ("stationary" in self._devicetracker_zone.lower() + or self._devicetracker_zone.lower() == "away" + or self._devicetracker_zone.lower() == "not_home" + or self._devicetracker_zone.lower() == "notset") + and place_name != "house": new_state = place_name if "house_number" in osm_decoded["address"]: @@ -1001,6 +1012,7 @@ def do_update(self, reason): "stationary" in self._devicetracker_zone.lower() or self._devicetracker_zone.lower() == "away" or self._devicetracker_zone.lower() == "not_home" + or self._devicetracker_zone.lower() == "notset" ): if ( self._direction != "stationary" @@ -1075,8 +1087,10 @@ def do_update(self, reason): "(" + self._name + ") New State using formatted_place: " + new_state ) elif ( - self._devicetracker_zone.lower() == "not_home" - or "stationary" in self._devicetracker_zone.lower() + "stationary" in self._devicetracker_zone.lower() + or self._devicetracker_zone.lower() == "away" + or self._devicetracker_zone.lower() == "not_home" + or self._devicetracker_zone.lower() == "notset" ): # Options: "formatted_place, zone, zone_name, place, street_number, street, city, county, state, postal_code, country, formatted_address" From a6765f994b2a905b03d8a2c17c14b32d247d5172 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 21:04:35 -0400 Subject: [PATCH 247/329] Update sensor.py --- custom_components/places/sensor.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 43cb374a..cba17363 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -895,11 +895,12 @@ def do_update(self, reason): if "name:" + language in osm_decoded["namedetails"]: place_name = osm_decoded["namedetails"]["name:" + language] break - if ("stationary" in self._devicetracker_zone.lower() - or self._devicetracker_zone.lower() == "away" - or self._devicetracker_zone.lower() == "not_home" - or self._devicetracker_zone.lower() == "notset") - and place_name != "house": + if ( + "stationary" in self._devicetracker_zone.lower() + or self._devicetracker_zone.lower() == "away" + or self._devicetracker_zone.lower() == "not_home" + or self._devicetracker_zone.lower() == "notset" + ) and place_name != "house": new_state = place_name if "house_number" in osm_decoded["address"]: From 3666b1aae93c61d1e7e6f9c993e1f227399e373b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Tue, 13 Sep 2022 21:05:28 -0400 Subject: [PATCH 248/329] :art: Format Python code with isort & Black Code Formatter (#112) --- custom_components/places/sensor.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index cba17363..2b47cc1d 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -540,10 +540,16 @@ def do_update(self, reason): "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id ) _LOGGER.debug( - "(" + self._name + ") DeviceTracker Attribute: " + str(hasattr(self, "_devicetracker_id")) + "(" + + self._name + + ") DeviceTracker Attribute: " + + str(hasattr(self, "_devicetracker_id")) ) _LOGGER.debug( - "(" + self._name + ") DeviceTracker Entity: " + str(self._hass.states.get(self._devicetracker_id)) + "(" + + self._name + + ") DeviceTracker Entity: " + + str(self._hass.states.get(self._devicetracker_id)) ) if ( From 7c029c9e0ffc3c44d70fa049391f8b370c379a4d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 18:23:06 -0400 Subject: [PATCH 249/329] Update sensor.py --- custom_components/places/sensor.py | 472 ++++++++++++----------------- 1 file changed, 186 insertions(+), 286 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 2b47cc1d..419e91ba 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -3,152 +3,14 @@ Original Author: Jim Thompson Subsequent Author: Ian Richardson +Current Author: Snuffy2 Description: Provides a sensor with a variable state consisting of reverse geocode (place) details for a linked device_tracker entity that provides GPS co-ordinates (ie owntracks, icloud) Optionally allows you to specify a 'home_zone' for each device and calculates distance from home and direction of travel. - Configuration Instructions are below - as well as sample automations for notifications. + Configuration Instructions are on GitHub. - The display options I have set for Sharon are "zone, place" so her state is displayed as: - - not_home, Richmond Hill GO Station, building, building, Beverley Acres, 6, Newkirk Road - There are a lot of additional attributes (beyond state) that are available which can be used in notifications, alerts, etc: - (The "home latitude/longitudes" below have been randomized to protect her privacy) -{ - "formatted_address": "Richmond Hill GO Station, 6, Newkirk Road, Beverley Acres, Richmond Hill, York Region, Ontario, L4C 1B3, Canada", - "friendly_name": "sharon", - "current_latitude": "43.874149009154095", - "distance_from_home_km": 7.24, - "country": "Canada", - "postal_code": "L4C 1B3", - "direction_of_travel": "towards home", - "neighbourhood": "Beverley Acres", - "entity_picture": "/local/sharon.png", - "street_number": "6", - "devicetracker_entityid": "device_tracker.sharon_iphone7", - "home_longitude": "-79.7323453871", - "devicetracker_zone": "not_home", - "distance_from_home_m": 17239.053, - "home_latitude": "43.983234888", - "previous_location": "43.86684124904056,-79.4253896502715", - "previous_longitude": "-79.4253896502715", - "place_category": "building", - "map_link": "https://maps.apple.com/maps/?ll=43.874149009154095,-79.42642783709209&z=18", - "last_changed": "2018-05-02 13:44:51.019837", - "state_province": "Ontario", - "county": "York Region", - "current_longitude": "-79.42642783709209", - "current_location": "43.874149009154095,-79.42642783709209", - "place_type": "building", - "previous_latitude": "43.86684124904056", - "place_name": "Richmond Hill GO Station", - "street": "Newkirk Road", - "city": "Richmond Hill", - "home_zone": "zone.sharon_home" -} - -Note: The Google Map Link for above location would have been: - https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=43.874149009154095,-79.42642783709209 - -Sample Configuration.yaml configurations: -sensor places_jim: - - platform: places - name: jim - devicetracker_id: device_tracker.jim_iphone8 - options: zone,place - display_zone: show - map_provider: google - map_zoom: 19 - home_zone: zone.jim_home - api_key: !secret email_jim - -sensor places_sharon: - - platform: places - name: sharon - devicetracker_id: device_tracker.sharon_iphone7 - options: zone, place - map_provider: apple - map_zoom: 18 - home_zone: zone.sharon_home - api_key: !secret email_sharon - -sensor places_aidan: - - platform: places - name: aidan - devicetracker_id: device_tracker.aidan_iphone7plus - options: place - map_provider: google - map_zoom: 17 - home_zone: zone.aidan_home - api_key: !secret email_aidan - -Sample generic automations.yaml snippet to send an iOS notify on any device state change: -(the only difference is the second one uses a condition to only trigger for a specific user) - -- alias: ReverseLocateEveryone - initial_state: 'on' - trigger: - platform: event - event_type: places_state_update - action: - - service: notify.ios_jim_iphone8 - data_template: - title: 'ReverseLocate: {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }}' - message: |- - {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) - {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} - {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) - data: - attachment: - url: '{{ trigger.event.data.map }}' - hide_thumbnail: false - -- alias: ReverseLocateAidan - initial_state: 'on' - trigger: - platform: event - event_type: places_state_update - condition: - condition: template - value_template: '{{ trigger.event.data.entity == "aidan" }}' - action: - - service: notify.ios_jim_iphone8 - data_template: - title: 'ReverseLocate: {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }}' - message: |- - {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) - {{ trigger.event.data.place_name }} - {{ trigger.event.data.distance_from_home_km }} from home and traveling {{ trigger.event.data.direction }} - {{ trigger.event.data.to_state }} ({{ trigger.event.data.mtime }}) - data: - attachment: - url: '{{ trigger.event.data.map }}' - hide_thumbnail: false - - -Note: The OpenStreetMap database is very flexible with regards to tag_names in their database schema. If you come across a set of co-ordinates that do not parse properly, you can enable debug messages to see the actual JSON that is returned from the query. - -Note: The OpenStreetMap API requests that you include your valid e-mail address in each API call if you are making a large numbers of requests. They say that this information will be kept confidential and only used to contact you in the event of a problem, see their Usage Policy for more details. - -Configuration.yaml: - sensor places_jim: - - platform: Places - name: jim (optional) - devicetracker_id: device_tracker.jim_iphone (required) - home_zone: zone.home (optional) - api_key: (optional) - map_provider: [google|apple] (optional) - map_zoom: <1-20> (optional) - option: (optional) - -The map link that gets generated for Google & Apple maps has a push pin marking the users location. - -To enable detailed logging for this component, add the following to your configuration.yaml file - logger: - default: warning - logs: - custom_components.sensor.places: debug - +GitHub: /~https://github.com/Snuffy2/places """ import json @@ -245,7 +107,7 @@ vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): cv.string, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): cv.string, vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): cv.string, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_NAME): cv.string, vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.positive_int, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, @@ -265,7 +127,7 @@ async def async_setup_entry( config = hass.data[DOMAIN][config_entry.entry_id] unique_id = config_entry.entry_id name = config.get(CONF_NAME) - _LOGGER.debug("config: " + str(config)) + _LOGGER.debug("[async_setup_entry] config: " + str(config)) async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) @@ -275,9 +137,15 @@ class Places(Entity): def __init__(self, hass, config, name, unique_id): """Initialize the sensor.""" - _LOGGER.debug("New places sensor: " + str(name)) - _LOGGER.debug("(" + str(name) + ") unique_id: " + str(unique_id)) - _LOGGER.debug("(" + str(name) + ") config: " + str(config)) + _LOGGER.debug("[Init] New places sensor: " + str(name)) + _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) + _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) + if hasattr(self,"entity_id"): + _LOGGER.debug("(" + str(name) + ") [Init] Entity ID: " + str(self.entity_id)) + _LOGGER.debug("(" + str(name) + ") [Init] Entity ID Type: " + str(type(self.entity_id))) + _LOGGER.debug("(" + str(name) + ") [Init] Entity Data: " + str(hass.states.get(str(self.entity_id)))) + else: + _LOGGER.debug("(" + str(name) + ") [Init] Entity ID: not defined") self._hass = hass self._name = name @@ -352,7 +220,7 @@ def __init__(self, hass, config, name, unique_id): # Check if devicetracker_id was specified correctly _LOGGER.info( - "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id + "(" + self._name + ") [Init] DeviceTracker Entity ID: " + self._devicetracker_id ) # if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: @@ -364,7 +232,7 @@ def __init__(self, hass, config, name, unique_id): from_state=None, to_state=None, ) - _LOGGER.info("(" + self._name + ") Now subscribed to state change events") + _LOGGER.info("(" + self._name + ") [Init] Subscribed to DeviceTracker state change events") @property def name(self): @@ -476,14 +344,55 @@ def extra_state_attributes(self): # _LOGGER.debug("(" + self._name + ") Extra State Attributes - " + return_attr) return return_attr + def is_devicetracker_set(self): + #_LOGGER.debug( + # "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id + #) + #_LOGGER.debug( + # "(" + # + self._name + # + ") DeviceTracker Attribute Exists: " + # + str(hasattr(self, "_devicetracker_id")) + #) + #_LOGGER.debug( + # "(" + # + self._name + # + ") DeviceTracker Entity: " + # + str(self._hass.states.get(self._devicetracker_id)) + #) + _LOGGER.debug( + "(" + + self._name + + ") [is_devicetracker_set] DeviceTracker State: " + + str(self._hass.states.get(self._devicetracker_id).state if self._hass.states.get(self._devicetracker_id) is not None else None) + ) + + if ( + hasattr(self, "_devicetracker_id") + and self._hass.states.get(self._devicetracker_id) is not None + and self._hass.states.get(self._devicetracker_id).state.lower() != "notset" + ): + return True + else: + return False + def tsc_update(self, tscarg2, tsarg3, tsarg4): """Call the do_update function based on the TSC (track state change) event""" - self.do_update("Track State Change") + if self.is_devicetracker_set(): + _LOGGER.debug("(" + self._name + ") [TSC Update] Running Update - Devicetracker is set") + self.do_update("Track State Change") + else: + _LOGGER.debug("(" + self._name + ") [TSC Update] Not Running Update - Devicetracker is not set") @Throttle(THROTTLE_INTERVAL) async def async_update(self): """Call the do_update function based on scan interval and throttle""" - await self._hass.async_add_executor_job(self.do_update("Scan Interval")) + if self.is_devicetracker_set(): + _LOGGER.debug("(" + self._name + ") [Async Update] Running Update - Devicetracker is set") + #await self._hass.async_add_executor_job(self.do_update("Scan Interval")) + self.do_update("Scan Interval") + else: + _LOGGER.debug("(" + self._name + ") [Async Update] Not Running Update - Devicetracker is not set") def haversine(self, lon1, lat1, lon2, lat2): """ @@ -507,12 +416,24 @@ def is_float(self, value): return True except ValueError: return False + + def in_zone(self): + if ( + "stationary" in self._devicetracker_zone.lower() + or self._devicetracker_zone.lower() == "away" + or self._devicetracker_zone.lower() == "not_home" + or self._devicetracker_zone.lower() == "notset" + ): + return False + else: + return True def do_update(self, reason): """Get the latest data and updates the states.""" _LOGGER.info("(" + self._name + ") Starting Update...") - previous_state = self.state + previous_state = self._state + new_state = None distance_traveled = 0 devicetracker_zone = None devicetracker_zone_id = None @@ -530,28 +451,19 @@ def do_update(self, reason): last_place_name = None prev_last_place_name = None - _LOGGER.info("(" + self._name + ") Calling update due to " + reason) + _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) + if hasattr(self,"entity_id"): + _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) + _LOGGER.debug("(" + self._name + ") Entity ID Type: " + str(type(self.entity_id))) + _LOGGER.debug("(" + self._name + ") Entity Data: " + str(self._hass.states.get(str(self.entity_id)))) + else: + _LOGGER.debug("(" + self._name + ") Entity ID: not defined") _LOGGER.info( - "(" + self._name + ") Check if update req'd: " + self._devicetracker_id - ) - _LOGGER.debug("(" + self._name + ") Previous State: " + previous_state) - - _LOGGER.debug( - "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id - ) - _LOGGER.debug( - "(" - + self._name - + ") DeviceTracker Attribute: " - + str(hasattr(self, "_devicetracker_id")) - ) - _LOGGER.debug( - "(" - + self._name - + ") DeviceTracker Entity: " - + str(self._hass.states.get(self._devicetracker_id)) + "(" + self._name + ") Check if update req'd: " + str(self._devicetracker_id) ) + _LOGGER.debug("(" + self._name + ") Previous State: " + str(previous_state)) + #Can remove this 'if' now since we are checking before calling do_update if ( hasattr(self, "_devicetracker_id") and self._hass.states.get(self._devicetracker_id) is not None @@ -594,12 +506,7 @@ def do_update(self, reason): + str(self._last_place_name) ) - if ( - "stationary" in self._devicetracker_zone.lower() - or self._devicetracker_zone.lower() == "away" - or self._devicetracker_zone.lower() == "not_home" - or self._devicetracker_zone.lower() == "notset" - ): + if not self.in_zone(): # Not in a Zone if self._place_name is not None and self._place_name != "-": # If place name is set @@ -608,8 +515,7 @@ def do_update(self, reason): "(" + self._name + ") Previous Place Name is set: " - + last_place_name - + ", updating" + + str(last_place_name) ) else: # If blank, keep previous last place name @@ -617,7 +523,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Previous Place Name is None or -, keeping prior" + + ") Previous Place Name is None, keeping prior" ) else: # In a Zone @@ -626,8 +532,7 @@ def do_update(self, reason): "(" + self._name + ") Previous Place is Zone: " - + last_place_name - + ", updating" + + str(last_place_name) ) _LOGGER.debug( "(" @@ -638,26 +543,26 @@ def do_update(self, reason): maplink_apple = ( "https://maps.apple.com/maps/?q=" - + current_location + + str(current_location) + "&z=" + str(self._map_zoom) ) # maplink_google = 'https://www.google.com/maps/dir/?api=1&origin=' + current_location + '&destination=' + home_location + '&travelmode=driving&layer=traffic' maplink_google = ( "https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=" - + current_location + + str(current_location) ) maplink_osm = ( "https://www.openstreetmap.org/?mlat=" - + new_latitude + + str(new_latitude) + "&mlon=" - + new_longitude + + str(new_longitude) + "#map=" + str(self._map_zoom) + "/" - + new_latitude[:8] + + str(new_latitude)[:8] + "/" - + new_longitude[:9] + + str(new_longitude)[:9] ) if ( new_latitude is not None @@ -689,12 +594,12 @@ def do_update(self, reason): direction = "stationary" _LOGGER.debug( - "(" + self._name + ") Previous Location: " + previous_location + "(" + self._name + ") Previous Location: " + str(previous_location) ) _LOGGER.debug( - "(" + self._name + ") Current Location: " + current_location + "(" + self._name + ") Current Location: " + str(current_location) ) - _LOGGER.debug("(" + self._name + ") Home Location: " + home_location) + _LOGGER.debug("(" + self._name + ") Home Location: " + str(home_location)) _LOGGER.info( "(" + self._name @@ -704,20 +609,20 @@ def do_update(self, reason): + str(distance_km) + " km" ) - _LOGGER.info("(" + self._name + ") Travel Direction: " + direction) + _LOGGER.info("(" + self._name + ") Travel Direction: " + str(direction)) """Update if location has changed.""" devicetracker_zone = self._hass.states.get(self._devicetracker_id).state _LOGGER.info( - "(" + self._name + ") DeviceTracker Zone: " + devicetracker_zone + "(" + self._name + ") DeviceTracker Zone: " + str(devicetracker_zone) ) devicetracker_zone_id = self._hass.states.get( self._devicetracker_id ).attributes.get("zone") if devicetracker_zone_id is not None: - devicetracker_zone_id = "zone." + devicetracker_zone_id + devicetracker_zone_id = "zone." + str(devicetracker_zone_id) devicetracker_zone_name_state = self._hass.states.get( devicetracker_zone_id ) @@ -729,7 +634,7 @@ def do_update(self, reason): "(" + self._name + ") DeviceTracker Zone Name: " - + devicetracker_zone_name + + str(devicetracker_zone_name) ) distance_traveled = distance( @@ -750,13 +655,13 @@ def do_update(self, reason): "(" + self._name + ") Problem with updated lat/long, this will likely error: new_latitude=" - + new_latitude + + str(new_latitude) + ", new_longitude=" - + new_longitude + + str(new_longitude) + ", home_latitude=" - + home_latitude + + str(home_latitude) + ", home_longitude=" - + home_longitude + + str(home_longitude) ) else: _LOGGER.error( @@ -807,7 +712,7 @@ def do_update(self, reason): "(" + self._name + ") DeviceTracker Zone (current): " - + self._devicetracker_zone + + str(self._devicetracker_zone) + " / Skipped Updates: " + str(self._updateskipped) ) @@ -832,21 +737,22 @@ def do_update(self, reason): self._map_link = maplink_osm else: self._map_link = maplink_apple - _LOGGER.debug("(" + self._name + ") Map Link Type: " + self._map_provider) - _LOGGER.debug("(" + self._name + ") Map Link generated: " + self._map_link) + _LOGGER.debug("(" + self._name + ") Map Link Type: " + str(self._map_provider)) + _LOGGER.debug("(" + self._name + ") Map Link generated: " + str(self._map_link)) + # Change logic and default_key for api-Key osm_url = ( "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" - + self._latitude + + str(self._latitude) + "&lon=" - + self._longitude + + str(self._longitude) + ( - "&accept-language=" + self._language + "&accept-language=" + str(self._language) if self._language != DEFAULT_LANGUAGE else "" ) + "&addressdetails=1&namedetails=1&zoom=18&limit=1" - + ("&email=" + self._api_key if self._api_key != DEFAULT_KEY else "") + + ("&email=" + str(self._api_key) if self._api_key != DEFAULT_KEY else "") ) osm_decoded = {} @@ -854,11 +760,11 @@ def do_update(self, reason): "(" + self._name + ") OpenStreetMap Request: lat=" - + self._latitude + + str(self._latitude) + " and lon=" - + self._longitude + + str(self._longitude) ) - _LOGGER.debug("(" + self._name + ") OSM URL: " + osm_url) + _LOGGER.debug("(" + self._name + ") OSM URL: " + str(osm_url)) osm_response = get(osm_url) osm_json_input = osm_response.text _LOGGER.debug("(" + self._name + ") OSM Response: " + osm_json_input) @@ -901,12 +807,7 @@ def do_update(self, reason): if "name:" + language in osm_decoded["namedetails"]: place_name = osm_decoded["namedetails"]["name:" + language] break - if ( - "stationary" in self._devicetracker_zone.lower() - or self._devicetracker_zone.lower() == "away" - or self._devicetracker_zone.lower() == "not_home" - or self._devicetracker_zone.lower() == "notset" - ) and place_name != "house": + if not self.in_zone() and place_name != "house": new_state = place_name if "house_number" in osm_decoded["address"]: @@ -1015,12 +916,7 @@ def do_update(self, reason): # Formatted Place formatted_place_array = [] - if ( - "stationary" in self._devicetracker_zone.lower() - or self._devicetracker_zone.lower() == "away" - or self._devicetracker_zone.lower() == "not_home" - or self._devicetracker_zone.lower() == "notset" - ): + if not self.in_zone(): if ( self._direction != "stationary" and ( @@ -1083,7 +979,7 @@ def do_update(self, reason): if "error_message" in osm_decoded: new_state = osm_decoded["error_message"] - _LOGGER.info( + _LOGGER.warning( "(" + self._name + ") An error occurred contacting the web service for OpenStreetMap" @@ -1091,14 +987,9 @@ def do_update(self, reason): elif "formatted_place" in display_options: new_state = self._formatted_place _LOGGER.info( - "(" + self._name + ") New State using formatted_place: " + new_state + "(" + self._name + ") New State using formatted_place: " + str(new_state) ) - elif ( - "stationary" in self._devicetracker_zone.lower() - or self._devicetracker_zone.lower() == "away" - or self._devicetracker_zone.lower() == "not_home" - or self._devicetracker_zone.lower() == "notset" - ): + elif not self.in_zone(): # Options: "formatted_place, zone, zone_name, place, street_number, street, city, county, state, postal_code, country, formatted_address" @@ -1106,7 +997,7 @@ def do_update(self, reason): "(" + self._name + ") Building State from Display Options: " - + self._options + + str(self._options) ) user_display = [] @@ -1117,48 +1008,52 @@ def do_update(self, reason): if ( "zone_name" in display_options and "do_not_show_not_home" not in display_options + and self._devicetracker_zone_name is not None ): - zone = self._devicetracker_zone + #zone = self._devicetracker_zone user_display.append(self._devicetracker_zone_name) elif ( "zone" in display_options and "do_not_show_not_home" not in display_options + and self._devicetracker_zone is not None ): - zone = self._devicetracker_zone + #zone = self._devicetracker_zone user_display.append(self._devicetracker_zone) - if "place_name" in display_options: - if place_name is not None: + if "place_name" in display_options and place_name is not None: user_display.append(place_name) if "place" in display_options: if place_name is not None: user_display.append(place_name) - if place_category.lower() != "place": + if place_category is not None and place_category.lower() != "place": user_display.append(place_category) - if place_type.lower() != "yes": + if place_type is not None and place_type.lower() != "yes": user_display.append(place_type) - user_display.append(place_neighbourhood) - user_display.append(street_number) - user_display.append(street) + if place_neighbourhood is not None: + user_display.append(place_neighbourhood) + if street_number is not None: + user_display.append(street_number) + if street is not None: + user_display.append(street) else: - if "street_number" in display_options: + if "street_number" in display_options and street_number is not None: user_display.append(street_number) - if "street" in display_options: + if "street" in display_options and street is not None: user_display.append(street) - if "city" in display_options: - user_display.append(city) - if "county" in display_options: - user_display.append(county) - if "state" in display_options: - user_display.append(region) - elif "region" in display_options: - user_display.append(region) - if "postal_code" in display_options: - user_display.append(postal_code) - if "country" in display_options: - user_display.append(country) - if "formatted_address" in display_options: - user_display.append(formatted_address) + if "city" in display_options and self._city is not None: + user_display.append(self._city) + if "county" in display_options and self._county is not None: + user_display.append(self._county) + if "state" in display_options and self._region is not None: + user_display.append(self._region) + elif "region" in display_options and self._region is not None: + user_display.append(self._region) + if "postal_code" in display_options and self._postal_code is not None: + user_display.append(self._postal_code) + if "country" in display_options and self._country is not None: + user_display.append(self._country) + if "formatted_address" in display_options and self._formatted_address is not None: + user_display.append(self._formatted_address) if "do_not_reorder" in display_options: user_display = [] @@ -1171,32 +1066,29 @@ def do_update(self, reason): if option in locals(): user_display.append(target_option) - if not user_display: - user_display = self._devicetracker_zone - user_display.append(street) - user_display.append(city) - - new_state = ", ".join(item for item in user_display) + if user_display: + new_state = ", ".join(item for item in user_display) _LOGGER.debug( - "(" + self._name + ") New State from Display Options: " + new_state + "(" + self._name + ") New State from Display Options: " + str(new_state) ) - elif "zone_name" in display_options: - new_state = devicetracker_zone_name + elif "zone_name" in display_options and self._devicetracker_zone_name is not None: + new_state = self._devicetracker_zone_name _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker Zone Name: " - + new_state + + str(new_state) ) - else: + elif self._devicetracker_zone is not None: new_state = devicetracker_zone _LOGGER.debug( "(" + self._name + ") New State from DeviceTracker Zone: " - + new_state + + str(new_state) ) + if self._extended_attr: self._osm_dict = osm_decoded current_time = "%02d:%02d" % (now.hour, now.minute) @@ -1220,12 +1112,12 @@ def do_update(self, reason): osm_details_url = ( "https://nominatim.openstreetmap.org/details.php?osmtype=" - + osm_type_abbr + + str(osm_type_abbr) + "&osmid=" - + osm_id + + str(osm_id) + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" + ( - "&email=" + self._api_key + "&email=" + str(self._api_key) if self._api_key != DEFAULT_KEY else "" ) @@ -1235,14 +1127,14 @@ def do_update(self, reason): "(" + self._name + ") OpenStreetMap Details Request: type=" - + osm_type + + str(osm_type) + " (" - + osm_type_abbr + + str(osm_type_abbr) + ") and id=" + str(osm_id) ) _LOGGER.debug( - "(" + self._name + ") OSM Details URL: " + osm_details_url + "(" + self._name + ") OSM Details URL: " + str(osm_details_url) ) osm_details_response = get(osm_details_url) if "error_message" in osm_details_response: @@ -1275,7 +1167,7 @@ def do_update(self, reason): if wikidata_id is not None: wikidata_url = ( "https://www.wikidata.org/wiki/Special:EntityData/" - + wikidata_id + + str(wikidata_id) + ".json" ) @@ -1283,10 +1175,10 @@ def do_update(self, reason): "(" + self._name + ") Wikidata Request: id=" - + wikidata_id + + str(wikidata_id) ) _LOGGER.debug( - "(" + self._name + ") Wikidata URL: " + wikidata_url + "(" + self._name + ") Wikidata URL: " + str(wikidata_url) ) wikidata_response = get(wikidata_url) if "error_message" in wikidata_response: @@ -1305,16 +1197,25 @@ def do_update(self, reason): + ") Wikidata JSON: " + wikidata_json_input ) - _LOGGER.debug( - "(" - + self._name - + ") Wikidata Dict: " - + str(wikidata_dict) - ) + #_LOGGER.debug( + # "(" + # + self._name + # + ") Wikidata Dict: " + # + str(wikidata_dict) + #) self._wikidata_dict = wikidata_dict + if new_state is not None: + _LOGGER.debug("(" + self._name + ") New State (Final): " + str(new_state)) + self._state = new_state[:255] + else: + self._state = "" + _LOGGER.warning( + "(" + + self._name + + ") New State is None, setting to: " + + str(self._state) + ) _LOGGER.debug("(" + self._name + ") Building EventData") - new_state = new_state[:255] - self._state = new_state event_data = {} event_data["entity"] = self._name event_data["from_state"] = previous_state @@ -1362,10 +1263,9 @@ def do_update(self, reason): event_data[ATTR_OSM_DETAILS_DICT] = osm_details_dict if wikidata_dict is not None: event_data[ATTR_WIKIDATA_DICT] = wikidata_dict - # _LOGGER.debug( "(" + self._name + ") Event Data: " + event_data ) - self._hass.bus.fire(DEFAULT_NAME + "_state_update", event_data) + self._hass.bus.fire(DOMAIN + "_state_update", event_data) _LOGGER.debug( - "(" + self._name + ") EventData updated: " + str(event_data) + "(" + self._name + ") Event Fired [event_type: " + DOMAIN + "_state_update]: " + str(event_data) ) else: _LOGGER.debug( From 6b9f54fdbdb8faaa976590082b6afaa48073f99e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 18:23:55 -0400 Subject: [PATCH 250/329] :art: Format Python code with isort & Black Code Formatter (#113) --- custom_components/places/sensor.py | 169 +++++++++++++++++++++-------- 1 file changed, 126 insertions(+), 43 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 419e91ba..389acba0 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -140,10 +140,22 @@ def __init__(self, hass, config, name, unique_id): _LOGGER.debug("[Init] New places sensor: " + str(name)) _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) - if hasattr(self,"entity_id"): - _LOGGER.debug("(" + str(name) + ") [Init] Entity ID: " + str(self.entity_id)) - _LOGGER.debug("(" + str(name) + ") [Init] Entity ID Type: " + str(type(self.entity_id))) - _LOGGER.debug("(" + str(name) + ") [Init] Entity Data: " + str(hass.states.get(str(self.entity_id)))) + if hasattr(self, "entity_id"): + _LOGGER.debug( + "(" + str(name) + ") [Init] Entity ID: " + str(self.entity_id) + ) + _LOGGER.debug( + "(" + + str(name) + + ") [Init] Entity ID Type: " + + str(type(self.entity_id)) + ) + _LOGGER.debug( + "(" + + str(name) + + ") [Init] Entity Data: " + + str(hass.states.get(str(self.entity_id))) + ) else: _LOGGER.debug("(" + str(name) + ") [Init] Entity ID: not defined") @@ -220,7 +232,10 @@ def __init__(self, hass, config, name, unique_id): # Check if devicetracker_id was specified correctly _LOGGER.info( - "(" + self._name + ") [Init] DeviceTracker Entity ID: " + self._devicetracker_id + "(" + + self._name + + ") [Init] DeviceTracker Entity ID: " + + self._devicetracker_id ) # if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: @@ -232,7 +247,11 @@ def __init__(self, hass, config, name, unique_id): from_state=None, to_state=None, ) - _LOGGER.info("(" + self._name + ") [Init] Subscribed to DeviceTracker state change events") + _LOGGER.info( + "(" + + self._name + + ") [Init] Subscribed to DeviceTracker state change events" + ) @property def name(self): @@ -345,28 +364,32 @@ def extra_state_attributes(self): return return_attr def is_devicetracker_set(self): - #_LOGGER.debug( + # _LOGGER.debug( # "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id - #) - #_LOGGER.debug( + # ) + # _LOGGER.debug( # "(" # + self._name # + ") DeviceTracker Attribute Exists: " # + str(hasattr(self, "_devicetracker_id")) - #) - #_LOGGER.debug( + # ) + # _LOGGER.debug( # "(" # + self._name # + ") DeviceTracker Entity: " # + str(self._hass.states.get(self._devicetracker_id)) - #) + # ) _LOGGER.debug( "(" + self._name + ") [is_devicetracker_set] DeviceTracker State: " - + str(self._hass.states.get(self._devicetracker_id).state if self._hass.states.get(self._devicetracker_id) is not None else None) + + str( + self._hass.states.get(self._devicetracker_id).state + if self._hass.states.get(self._devicetracker_id) is not None + else None + ) ) - + if ( hasattr(self, "_devicetracker_id") and self._hass.states.get(self._devicetracker_id) is not None @@ -379,20 +402,36 @@ def is_devicetracker_set(self): def tsc_update(self, tscarg2, tsarg3, tsarg4): """Call the do_update function based on the TSC (track state change) event""" if self.is_devicetracker_set(): - _LOGGER.debug("(" + self._name + ") [TSC Update] Running Update - Devicetracker is set") + _LOGGER.debug( + "(" + + self._name + + ") [TSC Update] Running Update - Devicetracker is set" + ) self.do_update("Track State Change") else: - _LOGGER.debug("(" + self._name + ") [TSC Update] Not Running Update - Devicetracker is not set") + _LOGGER.debug( + "(" + + self._name + + ") [TSC Update] Not Running Update - Devicetracker is not set" + ) @Throttle(THROTTLE_INTERVAL) async def async_update(self): """Call the do_update function based on scan interval and throttle""" if self.is_devicetracker_set(): - _LOGGER.debug("(" + self._name + ") [Async Update] Running Update - Devicetracker is set") - #await self._hass.async_add_executor_job(self.do_update("Scan Interval")) + _LOGGER.debug( + "(" + + self._name + + ") [Async Update] Running Update - Devicetracker is set" + ) + # await self._hass.async_add_executor_job(self.do_update("Scan Interval")) self.do_update("Scan Interval") else: - _LOGGER.debug("(" + self._name + ") [Async Update] Not Running Update - Devicetracker is not set") + _LOGGER.debug( + "(" + + self._name + + ") [Async Update] Not Running Update - Devicetracker is not set" + ) def haversine(self, lon1, lat1, lon2, lat2): """ @@ -416,7 +455,7 @@ def is_float(self, value): return True except ValueError: return False - + def in_zone(self): if ( "stationary" in self._devicetracker_zone.lower() @@ -452,10 +491,17 @@ def do_update(self, reason): prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) - if hasattr(self,"entity_id"): + if hasattr(self, "entity_id"): _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) - _LOGGER.debug("(" + self._name + ") Entity ID Type: " + str(type(self.entity_id))) - _LOGGER.debug("(" + self._name + ") Entity Data: " + str(self._hass.states.get(str(self.entity_id)))) + _LOGGER.debug( + "(" + self._name + ") Entity ID Type: " + str(type(self.entity_id)) + ) + _LOGGER.debug( + "(" + + self._name + + ") Entity Data: " + + str(self._hass.states.get(str(self.entity_id))) + ) else: _LOGGER.debug("(" + self._name + ") Entity ID: not defined") _LOGGER.info( @@ -463,7 +509,7 @@ def do_update(self, reason): ) _LOGGER.debug("(" + self._name + ") Previous State: " + str(previous_state)) - #Can remove this 'if' now since we are checking before calling do_update + # Can remove this 'if' now since we are checking before calling do_update if ( hasattr(self, "_devicetracker_id") and self._hass.states.get(self._devicetracker_id) is not None @@ -599,7 +645,9 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name + ") Current Location: " + str(current_location) ) - _LOGGER.debug("(" + self._name + ") Home Location: " + str(home_location)) + _LOGGER.debug( + "(" + self._name + ") Home Location: " + str(home_location) + ) _LOGGER.info( "(" + self._name @@ -615,7 +663,10 @@ def do_update(self, reason): devicetracker_zone = self._hass.states.get(self._devicetracker_id).state _LOGGER.info( - "(" + self._name + ") DeviceTracker Zone: " + str(devicetracker_zone) + "(" + + self._name + + ") DeviceTracker Zone: " + + str(devicetracker_zone) ) devicetracker_zone_id = self._hass.states.get( @@ -737,8 +788,12 @@ def do_update(self, reason): self._map_link = maplink_osm else: self._map_link = maplink_apple - _LOGGER.debug("(" + self._name + ") Map Link Type: " + str(self._map_provider)) - _LOGGER.debug("(" + self._name + ") Map Link generated: " + str(self._map_link)) + _LOGGER.debug( + "(" + self._name + ") Map Link Type: " + str(self._map_provider) + ) + _LOGGER.debug( + "(" + self._name + ") Map Link generated: " + str(self._map_link) + ) # Change logic and default_key for api-Key osm_url = ( @@ -752,7 +807,11 @@ def do_update(self, reason): else "" ) + "&addressdetails=1&namedetails=1&zoom=18&limit=1" - + ("&email=" + str(self._api_key) if self._api_key != DEFAULT_KEY else "") + + ( + "&email=" + str(self._api_key) + if self._api_key != DEFAULT_KEY + else "" + ) ) osm_decoded = {} @@ -987,7 +1046,10 @@ def do_update(self, reason): elif "formatted_place" in display_options: new_state = self._formatted_place _LOGGER.info( - "(" + self._name + ") New State using formatted_place: " + str(new_state) + "(" + + self._name + + ") New State using formatted_place: " + + str(new_state) ) elif not self.in_zone(): @@ -1010,18 +1072,18 @@ def do_update(self, reason): and "do_not_show_not_home" not in display_options and self._devicetracker_zone_name is not None ): - #zone = self._devicetracker_zone + # zone = self._devicetracker_zone user_display.append(self._devicetracker_zone_name) elif ( "zone" in display_options and "do_not_show_not_home" not in display_options and self._devicetracker_zone is not None ): - #zone = self._devicetracker_zone + # zone = self._devicetracker_zone user_display.append(self._devicetracker_zone) if "place_name" in display_options and place_name is not None: - user_display.append(place_name) + user_display.append(place_name) if "place" in display_options: if place_name is not None: user_display.append(place_name) @@ -1052,7 +1114,10 @@ def do_update(self, reason): user_display.append(self._postal_code) if "country" in display_options and self._country is not None: user_display.append(self._country) - if "formatted_address" in display_options and self._formatted_address is not None: + if ( + "formatted_address" in display_options + and self._formatted_address is not None + ): user_display.append(self._formatted_address) if "do_not_reorder" in display_options: @@ -1069,9 +1134,15 @@ def do_update(self, reason): if user_display: new_state = ", ".join(item for item in user_display) _LOGGER.debug( - "(" + self._name + ") New State from Display Options: " + str(new_state) + "(" + + self._name + + ") New State from Display Options: " + + str(new_state) ) - elif "zone_name" in display_options and self._devicetracker_zone_name is not None: + elif ( + "zone_name" in display_options + and self._devicetracker_zone_name is not None + ): new_state = self._devicetracker_zone_name _LOGGER.debug( "(" @@ -1088,7 +1159,6 @@ def do_update(self, reason): + str(new_state) ) - if self._extended_attr: self._osm_dict = osm_decoded current_time = "%02d:%02d" % (now.hour, now.minute) @@ -1134,7 +1204,10 @@ def do_update(self, reason): + str(osm_id) ) _LOGGER.debug( - "(" + self._name + ") OSM Details URL: " + str(osm_details_url) + "(" + + self._name + + ") OSM Details URL: " + + str(osm_details_url) ) osm_details_response = get(osm_details_url) if "error_message" in osm_details_response: @@ -1178,7 +1251,10 @@ def do_update(self, reason): + str(wikidata_id) ) _LOGGER.debug( - "(" + self._name + ") Wikidata URL: " + str(wikidata_url) + "(" + + self._name + + ") Wikidata URL: " + + str(wikidata_url) ) wikidata_response = get(wikidata_url) if "error_message" in wikidata_response: @@ -1197,15 +1273,17 @@ def do_update(self, reason): + ") Wikidata JSON: " + wikidata_json_input ) - #_LOGGER.debug( + # _LOGGER.debug( # "(" # + self._name # + ") Wikidata Dict: " # + str(wikidata_dict) - #) + # ) self._wikidata_dict = wikidata_dict if new_state is not None: - _LOGGER.debug("(" + self._name + ") New State (Final): " + str(new_state)) + _LOGGER.debug( + "(" + self._name + ") New State (Final): " + str(new_state) + ) self._state = new_state[:255] else: self._state = "" @@ -1265,7 +1343,12 @@ def do_update(self, reason): event_data[ATTR_WIKIDATA_DICT] = wikidata_dict self._hass.bus.fire(DOMAIN + "_state_update", event_data) _LOGGER.debug( - "(" + self._name + ") Event Fired [event_type: " + DOMAIN + "_state_update]: " + str(event_data) + "(" + + self._name + + ") Event Fired [event_type: " + + DOMAIN + + "_state_update]: " + + str(event_data) ) else: _LOGGER.debug( From 2bd8c2efd9b192d3bf1799cc3fc885ef3d7a556d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 19:17:14 -0400 Subject: [PATCH 251/329] More --- custom_components/places/config_flow.py | 1 - custom_components/places/const.py | 3 -- custom_components/places/sensor.py | 41 +++++++++---------------- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 428fb638..7c2132cf 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -48,7 +48,6 @@ vol.Coerce(int), vol.Range(min=1, max=20) ), vol.Optional(CONF_LANGUAGE): str, - # vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): bool, } ) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 5c784af0..37c64ea2 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -1,5 +1,3 @@ -from datetime import timedelta - DOMAIN = "placesv2dev" # Defaults @@ -12,7 +10,6 @@ DEFAULT_MAP_ZOOM = 18 DEFAULT_LANGUAGE = "en" DEFAULT_EXTENDED_ATTR = False -SCAN_INTERVAL = timedelta(seconds=30) # Config CONF_DEVICETRACKER_ID = "devicetracker_id" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 389acba0..9cdabb77 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -31,6 +31,7 @@ from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL +from homeassistant.const import Platform from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle @@ -91,13 +92,13 @@ from .const import DEFAULT_LANGUAGE from .const import DEFAULT_MAP_PROVIDER from .const import DEFAULT_MAP_ZOOM -from .const import DEFAULT_NAME from .const import DEFAULT_OPTION from .const import DOMAIN -from .const import SCAN_INTERVAL THROTTLE_INTERVAL = timedelta(seconds=600) -TRACKABLE_DOMAINS = ["device_tracker"] +TRACKING_DOMAIN = "device_tracker" +HOME_LOCATION_DOMAIN = "" +SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) @@ -128,7 +129,10 @@ async def async_setup_entry( unique_id = config_entry.entry_id name = config.get(CONF_NAME) _LOGGER.debug("[async_setup_entry] config: " + str(config)) - + ### + _LOGGER.debug("(" + str(name) + ") [Init] Platform Type: " + str(type(Platform))) + _LOGGER.debug("(" + str(name) + ") [Init] Platform: " + str(Platform)) + ### async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) @@ -140,24 +144,6 @@ def __init__(self, hass, config, name, unique_id): _LOGGER.debug("[Init] New places sensor: " + str(name)) _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) - if hasattr(self, "entity_id"): - _LOGGER.debug( - "(" + str(name) + ") [Init] Entity ID: " + str(self.entity_id) - ) - _LOGGER.debug( - "(" - + str(name) - + ") [Init] Entity ID Type: " - + str(type(self.entity_id)) - ) - _LOGGER.debug( - "(" - + str(name) - + ") [Init] Entity Data: " - + str(hass.states.get(str(self.entity_id))) - ) - else: - _LOGGER.debug("(" + str(name) + ") [Init] Entity ID: not defined") self._hass = hass self._name = name @@ -491,17 +477,20 @@ def do_update(self, reason): prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) - if hasattr(self, "entity_id"): + if hasattr(self, "entity_id") and self.entity_id is not None: _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) - _LOGGER.debug( - "(" + self._name + ") Entity ID Type: " + str(type(self.entity_id)) - ) _LOGGER.debug( "(" + self._name + ") Entity Data: " + str(self._hass.states.get(str(self.entity_id))) ) + _LOGGER.debug( + "(" + + self._name + + ") Entity Friendly Name: " + + str(hass.states.get(str(self.entity_id)).attributes.get("friendly_name")) + ) else: _LOGGER.debug("(" + self._name + ") Entity ID: not defined") _LOGGER.info( From ad63fefb5e1fb976132dedb44e94ad3368b3d04b Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 19:46:04 -0400 Subject: [PATCH 252/329] Update sensor.py --- custom_components/places/sensor.py | 33 ++++++++++++++++-------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 9cdabb77..02680a58 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -32,6 +32,10 @@ from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import Platform +from homeassistant.const import ( + CONF_ENTITY_ID, + CONF_FRIENDLY_NAME, +) from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle @@ -131,7 +135,7 @@ async def async_setup_entry( _LOGGER.debug("[async_setup_entry] config: " + str(config)) ### _LOGGER.debug("(" + str(name) + ") [Init] Platform Type: " + str(type(Platform))) - _LOGGER.debug("(" + str(name) + ") [Init] Platform: " + str(Platform)) + _LOGGER.debug("(" + str(name) + ") [Init] Platform: " + str(list(Platform))) ### async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) @@ -479,20 +483,19 @@ def do_update(self, reason): _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) if hasattr(self, "entity_id") and self.entity_id is not None: _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) - _LOGGER.debug( - "(" - + self._name - + ") Entity Data: " - + str(self._hass.states.get(str(self.entity_id))) - ) - _LOGGER.debug( - "(" - + self._name - + ") Entity Friendly Name: " - + str(hass.states.get(str(self.entity_id)).attributes.get("friendly_name")) - ) - else: - _LOGGER.debug("(" + self._name + ") Entity ID: not defined") + #_LOGGER.debug( + # "(" + # + self._name + # + ") Entity Data: " + # + str(self._hass.states.get(str(self.entity_id))) + #) + if self._name != self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name"): + _LOGGER.debug("(" + + self._name + + ") Updating Name to: " + + str(self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name")) + ) + self._name = self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name") _LOGGER.info( "(" + self._name + ") Check if update req'd: " + str(self._devicetracker_id) ) From c376b443799a5e8304455bed95448bd067ea072e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 19:47:00 -0400 Subject: [PATCH 253/329] :art: Format Python code with isort & Black Code Formatter (#114) --- custom_components/places/sensor.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 02680a58..73af3b5b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -29,13 +29,11 @@ from homeassistant import core from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY +from homeassistant.const import CONF_ENTITY_ID +from homeassistant.const import CONF_FRIENDLY_NAME from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import Platform -from homeassistant.const import ( - CONF_ENTITY_ID, - CONF_FRIENDLY_NAME, -) from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle @@ -483,19 +481,28 @@ def do_update(self, reason): _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) if hasattr(self, "entity_id") and self.entity_id is not None: _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) - #_LOGGER.debug( + # _LOGGER.debug( # "(" # + self._name # + ") Entity Data: " # + str(self._hass.states.get(str(self.entity_id))) - #) - if self._name != self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name"): - _LOGGER.debug("(" + # ) + if self._name != self._hass.states.get(str(self.entity_id)).attributes.get( + "friendly_name" + ): + _LOGGER.debug( + "(" + self._name + ") Updating Name to: " - + str(self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name")) - ) - self._name = self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name") + + str( + self._hass.states.get(str(self.entity_id)).attributes.get( + "friendly_name" + ) + ) + ) + self._name = self._hass.states.get(str(self.entity_id)).attributes.get( + "friendly_name" + ) _LOGGER.info( "(" + self._name + ") Check if update req'd: " + str(self._devicetracker_id) ) From 3b9fef75d585ef805313182dd1bf5a9d1ae42f40 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 20:11:35 -0400 Subject: [PATCH 254/329] More refinements --- custom_components/places/__init__.py | 3 ++- custom_components/places/sensor.py | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 39a832dd..ff8eec33 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -2,6 +2,7 @@ from homeassistant import config_entries from homeassistant import core +from homeassistant.const import Platform from .const import DOMAIN @@ -15,7 +16,7 @@ # List of platforms to support. There should be a matching .py file for each, # eg and -PLATFORMS: list[str] = ["sensor"] +PLATFORMS: list[str] = [Platform.SENSOR] async def async_setup_entry( diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 02680a58..bc89a551 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -32,6 +32,7 @@ from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import Platform +from homeassistant.const import CONF_ZONE from homeassistant.const import ( CONF_ENTITY_ID, CONF_FRIENDLY_NAME, @@ -100,8 +101,8 @@ from .const import DOMAIN THROTTLE_INTERVAL = timedelta(seconds=600) -TRACKING_DOMAIN = "device_tracker" -HOME_LOCATION_DOMAIN = "" +TRACKING_DOMAIN = Platform.DEVICE_TRACKER +HOME_LOCATION_DOMAIN = CONF_ZONE SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) @@ -482,20 +483,20 @@ def do_update(self, reason): _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) if hasattr(self, "entity_id") and self.entity_id is not None: - _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) + #_LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) #_LOGGER.debug( # "(" # + self._name # + ") Entity Data: " # + str(self._hass.states.get(str(self.entity_id))) #) - if self._name != self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name"): + if self._name != self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME): _LOGGER.debug("(" + self._name + ") Updating Name to: " - + str(self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name")) + + str(self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME)) ) - self._name = self._hass.states.get(str(self.entity_id)).attributes.get("friendly_name") + self._name = self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME) _LOGGER.info( "(" + self._name + ") Check if update req'd: " + str(self._devicetracker_id) ) @@ -716,7 +717,7 @@ def do_update(self, reason): if current_location == previous_location: _LOGGER.debug( - "(" + self._name + ") Skipping update because coordinates are identical" + "(" + self._name + ") Stopping update because coordinates are identical" ) proceed_with_update = False elif int(distance_traveled) > 0 and self._updateskipped > 3: @@ -731,7 +732,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Skipping update because location changed " + + ") Stopping update because location changed " + str(round(distance_traveled, 1)) + " < 10m (" + str(self._updateskipped) From cf0a88257bbfe2f77848cb11dcb5b0dbc31ae59f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 20:15:17 -0400 Subject: [PATCH 255/329] :art: Format Python code with isort & Black Code Formatter (#115) --- custom_components/places/sensor.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b59d0c22..d214c173 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -33,8 +33,8 @@ from homeassistant.const import CONF_FRIENDLY_NAME from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL -from homeassistant.const import Platform from homeassistant.const import CONF_ZONE +from homeassistant.const import Platform from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle @@ -481,20 +481,29 @@ def do_update(self, reason): _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) if hasattr(self, "entity_id") and self.entity_id is not None: - #_LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) + # _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) # _LOGGER.debug( # "(" # + self._name # + ") Entity Data: " # + str(self._hass.states.get(str(self.entity_id))) - #) - if self._name != self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME): - _LOGGER.debug("(" + # ) + if self._name != self._hass.states.get(str(self.entity_id)).attributes.get( + CONF_FRIENDLY_NAME + ): + _LOGGER.debug( + "(" + self._name + ") Updating Name to: " - + str(self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME)) - ) - self._name = self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME) + + str( + self._hass.states.get(str(self.entity_id)).attributes.get( + CONF_FRIENDLY_NAME + ) + ) + ) + self._name = self._hass.states.get(str(self.entity_id)).attributes.get( + CONF_FRIENDLY_NAME + ) if self._name != self._hass.states.get(str(self.entity_id)).attributes.get( "friendly_name" ): From 00eb910bd3bb0b9b64638e16f6b6e2120fede9fe Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 20:33:21 -0400 Subject: [PATCH 256/329] Update sensor.py --- custom_components/places/sensor.py | 396 ++++++++++++++--------------- 1 file changed, 193 insertions(+), 203 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index d214c173..854adff2 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -29,7 +29,6 @@ from homeassistant import core from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_API_KEY -from homeassistant.const import CONF_ENTITY_ID from homeassistant.const import CONF_FRIENDLY_NAME from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL @@ -132,10 +131,6 @@ async def async_setup_entry( unique_id = config_entry.entry_id name = config.get(CONF_NAME) _LOGGER.debug("[async_setup_entry] config: " + str(config)) - ### - _LOGGER.debug("(" + str(name) + ") [Init] Platform Type: " + str(type(Platform))) - _LOGGER.debug("(" + str(name) + ") [Init] Platform: " + str(list(Platform))) - ### async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) @@ -148,6 +143,7 @@ def __init__(self, hass, config, name, unique_id): _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) + self._config = config self._hass = hass self._name = name self._unique_id = unique_id @@ -488,9 +484,7 @@ def do_update(self, reason): # + ") Entity Data: " # + str(self._hass.states.get(str(self.entity_id))) # ) - if self._name != self._hass.states.get(str(self.entity_id)).attributes.get( - CONF_FRIENDLY_NAME - ): + if self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME) is not None and self._name != self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME): _LOGGER.debug( "(" + self._name @@ -504,236 +498,232 @@ def do_update(self, reason): self._name = self._hass.states.get(str(self.entity_id)).attributes.get( CONF_FRIENDLY_NAME ) - if self._name != self._hass.states.get(str(self.entity_id)).attributes.get( - "friendly_name" - ): + if self._name != self._config[CONF_NAME]: + _LOGGER.debug( "(" + self._name - + ") Updating Name to: " - + str( - self._hass.states.get(str(self.entity_id)).attributes.get( - "friendly_name" - ) - ) - ) - self._name = self._hass.states.get(str(self.entity_id)).attributes.get( - "friendly_name" + + ") Updating Config Name: Old: " + + str(self._config[CONF_NAME]) + + ", New: " + + self._name ) + self._config[CONF_NAME] = self._name + _LOGGER.info( "(" + self._name + ") Check if update req'd: " + str(self._devicetracker_id) ) _LOGGER.debug("(" + self._name + ") Previous State: " + str(previous_state)) # Can remove this 'if' now since we are checking before calling do_update - if ( - hasattr(self, "_devicetracker_id") - and self._hass.states.get(self._devicetracker_id) is not None - ): - now = datetime.now() - old_latitude = str(self._latitude) - if not self.is_float(old_latitude): - old_latitude = None - old_longitude = str(self._longitude) - if not self.is_float(old_latitude): - old_latitude = None - new_latitude = str( - self._hass.states.get(self._devicetracker_id).attributes.get("latitude") - ) - if not self.is_float(new_latitude): - new_latitude = None - new_longitude = str( - self._hass.states.get(self._devicetracker_id).attributes.get( - "longitude" - ) - ) - if not self.is_float(new_longitude): - new_longitude = None - home_latitude = str(self._home_latitude) - if not self.is_float(home_latitude): - home_latitude = None - home_longitude = str(self._home_longitude) - if not self.is_float(home_longitude): - home_longitude = None - last_distance_m = self._distance_m - last_updated = self._mtime - current_location = new_latitude + "," + new_longitude - previous_location = old_latitude + "," + old_longitude - home_location = home_latitude + "," + home_longitude - prev_last_place_name = self._last_place_name - _LOGGER.debug( - "(" - + self._name - + ") Previous last_place_name: " - + str(self._last_place_name) + #if ( + # hasattr(self, "_devicetracker_id") + # and self._hass.states.get(self._devicetracker_id) is not None + #): + now = datetime.now() + old_latitude = str(self._latitude) + if not self.is_float(old_latitude): + old_latitude = None + old_longitude = str(self._longitude) + if not self.is_float(old_latitude): + old_latitude = None + new_latitude = str( + self._hass.states.get(self._devicetracker_id).attributes.get("latitude") + ) + if not self.is_float(new_latitude): + new_latitude = None + new_longitude = str( + self._hass.states.get(self._devicetracker_id).attributes.get( + "longitude" ) + ) + if not self.is_float(new_longitude): + new_longitude = None + home_latitude = str(self._home_latitude) + if not self.is_float(home_latitude): + home_latitude = None + home_longitude = str(self._home_longitude) + if not self.is_float(home_longitude): + home_longitude = None + last_distance_m = self._distance_m + last_updated = self._mtime + current_location = new_latitude + "," + new_longitude + previous_location = old_latitude + "," + old_longitude + home_location = home_latitude + "," + home_longitude + prev_last_place_name = self._last_place_name + _LOGGER.debug( + "(" + + self._name + + ") Previous last_place_name: " + + str(self._last_place_name) + ) - if not self.in_zone(): - # Not in a Zone - if self._place_name is not None and self._place_name != "-": - # If place name is set - last_place_name = self._place_name - _LOGGER.debug( - "(" - + self._name - + ") Previous Place Name is set: " - + str(last_place_name) - ) - else: - # If blank, keep previous last place name - last_place_name = self._last_place_name - _LOGGER.debug( - "(" - + self._name - + ") Previous Place Name is None, keeping prior" - ) - else: - # In a Zone - last_place_name = self._devicetracker_zone_name + if not self.in_zone(): + # Not in a Zone + if self._place_name is not None and self._place_name != "-": + # If place name is set + last_place_name = self._place_name _LOGGER.debug( "(" + self._name - + ") Previous Place is Zone: " + + ") Previous Place Name is set: " + str(last_place_name) ) + else: + # If blank, keep previous last place name + last_place_name = self._last_place_name + _LOGGER.debug( + "(" + + self._name + + ") Previous Place Name is None, keeping prior" + ) + else: + # In a Zone + last_place_name = self._devicetracker_zone_name _LOGGER.debug( "(" + self._name - + ") Last Place Name (Initial): " + + ") Previous Place is Zone: " + str(last_place_name) ) + _LOGGER.debug( + "(" + + self._name + + ") Last Place Name (Initial): " + + str(last_place_name) + ) - maplink_apple = ( - "https://maps.apple.com/maps/?q=" - + str(current_location) - + "&z=" - + str(self._map_zoom) - ) - # maplink_google = 'https://www.google.com/maps/dir/?api=1&origin=' + current_location + '&destination=' + home_location + '&travelmode=driving&layer=traffic' - maplink_google = ( - "https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=" - + str(current_location) - ) - maplink_osm = ( - "https://www.openstreetmap.org/?mlat=" - + str(new_latitude) - + "&mlon=" - + str(new_longitude) - + "#map=" - + str(self._map_zoom) - + "/" - + str(new_latitude)[:8] - + "/" - + str(new_longitude)[:9] + maplink_apple = ( + "https://maps.apple.com/maps/?q=" + + str(current_location) + + "&z=" + + str(self._map_zoom) + ) + # maplink_google = 'https://www.google.com/maps/dir/?api=1&origin=' + current_location + '&destination=' + home_location + '&travelmode=driving&layer=traffic' + maplink_google = ( + "https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=" + + str(current_location) + ) + maplink_osm = ( + "https://www.openstreetmap.org/?mlat=" + + str(new_latitude) + + "&mlon=" + + str(new_longitude) + + "#map=" + + str(self._map_zoom) + + "/" + + str(new_latitude)[:8] + + "/" + + str(new_longitude)[:9] + ) + if ( + new_latitude is not None + and new_longitude is not None + and home_latitude is not None + and home_longitude is not None + ): + distance_m = distance( + float(new_latitude), + float(new_longitude), + float(home_latitude), + float(home_longitude), ) - if ( - new_latitude is not None - and new_longitude is not None - and home_latitude is not None - and home_longitude is not None - ): - distance_m = distance( - float(new_latitude), - float(new_longitude), - float(home_latitude), - float(home_longitude), - ) - distance_km = round(distance_m / 1000, 3) + distance_km = round(distance_m / 1000, 3) - deviation = self.haversine( - float(old_latitude), - float(old_longitude), - float(new_latitude), - float(new_longitude), - ) - if deviation <= 0.2: # in kilometers - direction = "stationary" - elif last_distance_m > distance_m: - direction = "towards home" - elif last_distance_m < distance_m: - direction = "away from home" - else: - direction = "stationary" + deviation = self.haversine( + float(old_latitude), + float(old_longitude), + float(new_latitude), + float(new_longitude), + ) + if deviation <= 0.2: # in kilometers + direction = "stationary" + elif last_distance_m > distance_m: + direction = "towards home" + elif last_distance_m < distance_m: + direction = "away from home" + else: + direction = "stationary" - _LOGGER.debug( - "(" + self._name + ") Previous Location: " + str(previous_location) - ) - _LOGGER.debug( - "(" + self._name + ") Current Location: " + str(current_location) - ) - _LOGGER.debug( - "(" + self._name + ") Home Location: " + str(home_location) - ) - _LOGGER.info( - "(" - + self._name - + ") Distance from home [" - + (self._home_zone).split(".")[1] - + "]: " - + str(distance_km) - + " km" - ) - _LOGGER.info("(" + self._name + ") Travel Direction: " + str(direction)) + _LOGGER.debug( + "(" + self._name + ") Previous Location: " + str(previous_location) + ) + _LOGGER.debug( + "(" + self._name + ") Current Location: " + str(current_location) + ) + _LOGGER.debug( + "(" + self._name + ") Home Location: " + str(home_location) + ) + _LOGGER.info( + "(" + + self._name + + ") Distance from home [" + + (self._home_zone).split(".")[1] + + "]: " + + str(distance_km) + + " km" + ) + _LOGGER.info("(" + self._name + ") Travel Direction: " + str(direction)) - """Update if location has changed.""" + """Update if location has changed.""" - devicetracker_zone = self._hass.states.get(self._devicetracker_id).state - _LOGGER.info( - "(" - + self._name - + ") DeviceTracker Zone: " - + str(devicetracker_zone) - ) + devicetracker_zone = self._hass.states.get(self._devicetracker_id).state + _LOGGER.info( + "(" + + self._name + + ") DeviceTracker Zone: " + + str(devicetracker_zone) + ) - devicetracker_zone_id = self._hass.states.get( - self._devicetracker_id - ).attributes.get("zone") - if devicetracker_zone_id is not None: - devicetracker_zone_id = "zone." + str(devicetracker_zone_id) - devicetracker_zone_name_state = self._hass.states.get( - devicetracker_zone_id - ) - if devicetracker_zone_name_state is not None: - devicetracker_zone_name = devicetracker_zone_name_state.name - else: - devicetracker_zone_name = devicetracker_zone - _LOGGER.debug( - "(" - + self._name - + ") DeviceTracker Zone Name: " - + str(devicetracker_zone_name) + devicetracker_zone_id = self._hass.states.get( + self._devicetracker_id + ).attributes.get("zone") + if devicetracker_zone_id is not None: + devicetracker_zone_id = "zone." + str(devicetracker_zone_id) + devicetracker_zone_name_state = self._hass.states.get( + devicetracker_zone_id ) + if devicetracker_zone_name_state is not None: + devicetracker_zone_name = devicetracker_zone_name_state.name + else: + devicetracker_zone_name = devicetracker_zone + _LOGGER.debug( + "(" + + self._name + + ") DeviceTracker Zone Name: " + + str(devicetracker_zone_name) + ) - distance_traveled = distance( - float(new_latitude), - float(new_longitude), - float(old_latitude), - float(old_longitude), - ) + distance_traveled = distance( + float(new_latitude), + float(new_longitude), + float(old_latitude), + float(old_longitude), + ) - _LOGGER.info( - "(" - + self._name - + ") Meters traveled since last update: " - + str(round(distance_traveled, 1)) - ) - else: - _LOGGER.error( - "(" - + self._name - + ") Problem with updated lat/long, this will likely error: new_latitude=" - + str(new_latitude) - + ", new_longitude=" - + str(new_longitude) - + ", home_latitude=" - + str(home_latitude) - + ", home_longitude=" - + str(home_longitude) - ) + _LOGGER.info( + "(" + + self._name + + ") Meters traveled since last update: " + + str(round(distance_traveled, 1)) + ) else: _LOGGER.error( - "(" + self._name + ") Missing _devicetracker_id, this will likely error" + "(" + + self._name + + ") Problem with updated lat/long, this will likely error: new_latitude=" + + str(new_latitude) + + ", new_longitude=" + + str(new_longitude) + + ", home_latitude=" + + str(home_latitude) + + ", home_longitude=" + + str(home_longitude) ) + #else: + # _LOGGER.error( + # "(" + self._name + ") Missing _devicetracker_id, this will likely error" + # ) proceed_with_update = True initial_update = False From 2dc411cdef349ef2ec93fa222d41f9d793bf174c Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 20:34:07 -0400 Subject: [PATCH 257/329] :art: Format Python code with isort & Black Code Formatter (#116) --- custom_components/places/sensor.py | 43 ++++++++++++------------------ 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 854adff2..27540be9 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -484,7 +484,13 @@ def do_update(self, reason): # + ") Entity Data: " # + str(self._hass.states.get(str(self.entity_id))) # ) - if self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME) is not None and self._name != self._hass.states.get(str(self.entity_id)).attributes.get(CONF_FRIENDLY_NAME): + if self._hass.states.get(str(self.entity_id)).attributes.get( + CONF_FRIENDLY_NAME + ) is not None and self._name != self._hass.states.get( + str(self.entity_id) + ).attributes.get( + CONF_FRIENDLY_NAME + ): _LOGGER.debug( "(" + self._name @@ -499,7 +505,7 @@ def do_update(self, reason): CONF_FRIENDLY_NAME ) if self._name != self._config[CONF_NAME]: - + _LOGGER.debug( "(" + self._name @@ -516,10 +522,10 @@ def do_update(self, reason): _LOGGER.debug("(" + self._name + ") Previous State: " + str(previous_state)) # Can remove this 'if' now since we are checking before calling do_update - #if ( + # if ( # hasattr(self, "_devicetracker_id") # and self._hass.states.get(self._devicetracker_id) is not None - #): + # ): now = datetime.now() old_latitude = str(self._latitude) if not self.is_float(old_latitude): @@ -533,9 +539,7 @@ def do_update(self, reason): if not self.is_float(new_latitude): new_latitude = None new_longitude = str( - self._hass.states.get(self._devicetracker_id).attributes.get( - "longitude" - ) + self._hass.states.get(self._devicetracker_id).attributes.get("longitude") ) if not self.is_float(new_longitude): new_longitude = None @@ -573,24 +577,16 @@ def do_update(self, reason): # If blank, keep previous last place name last_place_name = self._last_place_name _LOGGER.debug( - "(" - + self._name - + ") Previous Place Name is None, keeping prior" + "(" + self._name + ") Previous Place Name is None, keeping prior" ) else: # In a Zone last_place_name = self._devicetracker_zone_name _LOGGER.debug( - "(" - + self._name - + ") Previous Place is Zone: " - + str(last_place_name) + "(" + self._name + ") Previous Place is Zone: " + str(last_place_name) ) _LOGGER.debug( - "(" - + self._name - + ") Last Place Name (Initial): " - + str(last_place_name) + "(" + self._name + ") Last Place Name (Initial): " + str(last_place_name) ) maplink_apple = ( @@ -651,9 +647,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name + ") Current Location: " + str(current_location) ) - _LOGGER.debug( - "(" + self._name + ") Home Location: " + str(home_location) - ) + _LOGGER.debug("(" + self._name + ") Home Location: " + str(home_location)) _LOGGER.info( "(" + self._name @@ -669,10 +663,7 @@ def do_update(self, reason): devicetracker_zone = self._hass.states.get(self._devicetracker_id).state _LOGGER.info( - "(" - + self._name - + ") DeviceTracker Zone: " - + str(devicetracker_zone) + "(" + self._name + ") DeviceTracker Zone: " + str(devicetracker_zone) ) devicetracker_zone_id = self._hass.states.get( @@ -720,7 +711,7 @@ def do_update(self, reason): + ", home_longitude=" + str(home_longitude) ) - #else: + # else: # _LOGGER.error( # "(" + self._name + ") Missing _devicetracker_id, this will likely error" # ) From 4b4d2b943638c11b83b715c4c6bb26d0f41aa716 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 21:45:54 -0400 Subject: [PATCH 258/329] Update sensor.py --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 27540be9..f4df0631 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -821,7 +821,7 @@ def do_update(self, reason): + str(self._longitude) ) _LOGGER.debug("(" + self._name + ") OSM URL: " + str(osm_url)) - osm_response = get(osm_url) + osm_response = await self._hass.async_add_executor_job(get,osm_url) osm_json_input = osm_response.text _LOGGER.debug("(" + self._name + ") OSM Response: " + osm_json_input) osm_decoded = json.loads(osm_json_input) From 9a49b3b23851f54bed338703630be6e9b962eae4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 21:47:02 -0400 Subject: [PATCH 259/329] :art: Format Python code with isort & Black Code Formatter (#117) --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index f4df0631..48c97f38 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -821,7 +821,7 @@ def do_update(self, reason): + str(self._longitude) ) _LOGGER.debug("(" + self._name + ") OSM URL: " + str(osm_url)) - osm_response = await self._hass.async_add_executor_job(get,osm_url) + osm_response = await self._hass.async_add_executor_job(get, osm_url) osm_json_input = osm_response.text _LOGGER.debug("(" + self._name + ") OSM Response: " + osm_json_input) osm_decoded = json.loads(osm_json_input) From 2d000f625a915cbf6e330f84b73c96f2f6fc40a5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 22:12:50 -0400 Subject: [PATCH 260/329] Update sensor.py --- custom_components/places/sensor.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 48c97f38..d9f9ea5f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -409,8 +409,8 @@ async def async_update(self): + self._name + ") [Async Update] Running Update - Devicetracker is set" ) - # await self._hass.async_add_executor_job(self.do_update("Scan Interval")) - self.do_update("Scan Interval") + await self._hass.async_add_executor_job(self.do_update,"Scan Interval") + #self.do_update("Scan Interval") else: _LOGGER.debug( "(" @@ -509,12 +509,16 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Updating Config Name: Old: " + + ") Updating Config Name - Old: " + str(self._config[CONF_NAME]) - + ", New: " - + self._name ) self._config[CONF_NAME] = self._name + _LOGGER.debug( + "(" + + self._name + + ") Updating Config Name - New: " + + str(self._config[CONF_NAME]) + ) _LOGGER.info( "(" + self._name + ") Check if update req'd: " + str(self._devicetracker_id) @@ -821,7 +825,7 @@ def do_update(self, reason): + str(self._longitude) ) _LOGGER.debug("(" + self._name + ") OSM URL: " + str(osm_url)) - osm_response = await self._hass.async_add_executor_job(get, osm_url) + osm_response = get(osm_url) osm_json_input = osm_response.text _LOGGER.debug("(" + self._name + ") OSM Response: " + osm_json_input) osm_decoded = json.loads(osm_json_input) From 7b8fd0569aaa3214fcdd0844cd92c0641ebd9fb2 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 22:17:56 -0400 Subject: [PATCH 261/329] :art: Format Python code with isort & Black Code Formatter (#118) --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index d9f9ea5f..1544a22d 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -409,8 +409,8 @@ async def async_update(self): + self._name + ") [Async Update] Running Update - Devicetracker is set" ) - await self._hass.async_add_executor_job(self.do_update,"Scan Interval") - #self.do_update("Scan Interval") + await self._hass.async_add_executor_job(self.do_update, "Scan Interval") + # self.do_update("Scan Interval") else: _LOGGER.debug( "(" From 2df0f7bca09dbe9bb745277887f6a0288ba2daf3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 22:58:15 -0400 Subject: [PATCH 262/329] Update sensor.py --- custom_components/places/sensor.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index d9f9ea5f..bad672ea 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -98,7 +98,7 @@ from .const import DOMAIN THROTTLE_INTERVAL = timedelta(seconds=600) -TRACKING_DOMAIN = Platform.DEVICE_TRACKER +TRACKING_DOMAIN = str(Platform.DEVICE_TRACKER) HOME_LOCATION_DOMAIN = CONF_ZONE SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) @@ -142,6 +142,8 @@ def __init__(self, hass, config, name, unique_id): _LOGGER.debug("[Init] New places sensor: " + str(name)) _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) + #_LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor Type: " + str(type(hass.data[TRACKING_DOMAIN]))) + #_LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor: " + list(hass.data[TRACKING_DOMAIN])) self._config = config self._hass = hass @@ -504,8 +506,22 @@ def do_update(self, reason): self._name = self._hass.states.get(str(self.entity_id)).attributes.get( CONF_FRIENDLY_NAME ) - if self._name != self._config[CONF_NAME]: + if self._name != self._hass.data[DOMAIN][self._unique_id][CONF_NAME]: + _LOGGER.debug( + "(" + + self._name + + ") Updating Hass Data Name - Old: " + + str(self._hass.data[DOMAIN][self._unique_id][CONF_NAME]) + ) + self._hass.data[DOMAIN][self._unique_id][CONF_NAME] = self._name + _LOGGER.debug( + "(" + + self._name + + ") Updating Hass Data Name - New: " + + str(self._hass.data[DOMAIN][self._unique_id][CONF_NAME]) + ) + if self._name != self._config[CONF_NAME]: _LOGGER.debug( "(" + self._name From 4995957fb1cb89f275bb43e50c3347dbea6215cf Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Wed, 14 Sep 2022 22:59:02 -0400 Subject: [PATCH 263/329] :art: Format Python code with isort & Black Code Formatter (#119) --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 117ff1ae..e188694e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -142,8 +142,8 @@ def __init__(self, hass, config, name, unique_id): _LOGGER.debug("[Init] New places sensor: " + str(name)) _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) - #_LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor Type: " + str(type(hass.data[TRACKING_DOMAIN]))) - #_LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor: " + list(hass.data[TRACKING_DOMAIN])) + # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor Type: " + str(type(hass.data[TRACKING_DOMAIN]))) + # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor: " + list(hass.data[TRACKING_DOMAIN])) self._config = config self._hass = hass From d64a2dd0f03afbeea4d1922246fd1f619343f7a9 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 16:54:02 -0400 Subject: [PATCH 264/329] More build refactoring --- custom_components/places/__init__.py | 1 + custom_components/places/sensor.py | 161 ++++++++++++++++++--------- 2 files changed, 112 insertions(+), 50 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index ff8eec33..4115b22a 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -26,6 +26,7 @@ async def async_setup_entry( # Store an instance of the "connecting" class that does the work of speaking # with your actual devices. ##hass.data.setdefault(DOMAIN, {})[entry.entry_id] = hub.Hub(hass, entry.data["host"]) + _LOGGER.debug("[init async_setup_entry] entry: " + str(entry.data)) hass.data.setdefault(DOMAIN, {}) hass_data = dict(entry.data) hass.data[DOMAIN][entry.entry_id] = hass_data diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e188694e..49d2ce83 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -38,6 +38,8 @@ from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle from homeassistant.util.location import distance +from homeassistant.helpers import device_registry, entity_registry +from homeassistant.const import ATTR_FRIENDLY_NAME from requests import get from .const import ATTR_CITY @@ -103,6 +105,12 @@ SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) +#### +full_domain_list = [] +zone_list = [] +device_tracker_list = [] +my_entity_id = None +my_entity_domain = None PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { @@ -120,6 +128,42 @@ ) +# From: core/homeassistant/components/homekit/config_flow.py +def _exclude_by_entity_registry( + ent_reg: entity_registry.EntityRegistry, + entity_id: str, + include_entity_category: bool, + include_hidden: bool, +) -> bool: + """Filter out hidden entities and ones with entity category (unless specified).""" + return bool( + (entry := ent_reg.async_get(entity_id)) + and ( + (not include_hidden and entry.hidden_by is not None) + or (not include_entity_category and entry.entity_category is not None) + ) + ) + +# From: core/homeassistant/components/homekit/config_flow.py +def _async_get_matching_entities( + hass: core.HomeAssistant, + domains: list[str] | None = None, + include_entity_category: bool = False, + include_hidden: bool = False, +) -> dict[str, str]: + """Fetch all entities or entities in the given domains.""" + ent_reg = entity_registry.async_get(hass) + return { + state.entity_id: f"{state.attributes.get(ATTR_FRIENDLY_NAME, state.entity_id)} ({state.entity_id})" + for state in sorted( + hass.states.async_all(domains and set(domains)), + key=lambda item: item.entity_id, + ) + if not _exclude_by_entity_registry( + ent_reg, state.entity_id, include_entity_category, include_hidden + ) + } + async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, @@ -130,22 +174,53 @@ async def async_setup_entry( config = hass.data[DOMAIN][config_entry.entry_id] unique_id = config_entry.entry_id name = config.get(CONF_NAME) - _LOGGER.debug("[async_setup_entry] config: " + str(config)) - async_add_entities([Places(hass, config, name, unique_id)], update_before_add=True) + #_LOGGER.debug("[async_setup_entry] config: " + str(config)) + #_LOGGER.debug("[async_setup_entry] hass: " + str(hass)) + #_LOGGER.debug("[async_setup_entry] hass data type: " + str(type(hass.data))) + #_LOGGER.debug("[async_setup_entry] hass data: " + str(hass.data)) + #_LOGGER.debug("[async_setup_entry] hass states: " + str(hass.states)) + #_LOGGER.debug("[async_setup_entry] hass states entity_ids: " + str(hass.states.async_entity_ids())) + _LOGGER.debug("[async_setup_entry] hass states device_tracker entity_ids: " + str(hass.states.async_entity_ids('device_tracker'))) + _LOGGER.debug("[async_setup_entry] hass states zone entity_ids: " + str(hass.states.async_entity_ids('zone'))) + #_LOGGER.debug("[async_setup_entry] hass components: " + str(hass.components)) + #_LOGGER.debug("[async_setup_entry] hass components type: " + str(type(hass.components))) + #_LOGGER.debug("[async_setup_entry] hass components device_tracker: " + str(hass.components.device_tracker)) + #_LOGGER.debug("[async_setup_entry] hass components zone: " + str(hass.components.zone)) + + + #compdict = [ s.component for s in hass.states.async_all() ] + #_LOGGER.debug("[async_setup_entry] hass components full list: " + str(compdict)) + #compdict = list(dict.fromkeys(compdict)) + #cnt = len(domains) + #compdict.sort() + + #compdict = [] + + #for component in hass.components: + # if component.count('.') == 0 and component not in compdict: + # compdict[component] = [] + # if component.count('.') == 1: + # domain, subdomain = component.split('.') + # compdict[domain].append(subdomain) + # + #_LOGGER.debug("[async_setup_entry] hass components domains list: " + str(compdict)) + + async_add_entities([Places(hass, config, config_entry, name, unique_id)], update_before_add=True) class Places(Entity): """Representation of a Places Sensor.""" - def __init__(self, hass, config, name, unique_id): + def __init__(self, hass, config, config_entry, name, unique_id): """Initialize the sensor.""" _LOGGER.debug("[Init] New places sensor: " + str(name)) - _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) - _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) + #_LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) + #_LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor Type: " + str(type(hass.data[TRACKING_DOMAIN]))) # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor: " + list(hass.data[TRACKING_DOMAIN])) self._config = config + self._config_entry = config_entry self._hass = hass self._name = name self._unique_id = unique_id @@ -351,31 +426,16 @@ def extra_state_attributes(self): return return_attr def is_devicetracker_set(self): - # _LOGGER.debug( - # "(" + self._name + ") DeviceTracker Entity ID: " + self._devicetracker_id - # ) - # _LOGGER.debug( + #_LOGGER.debug( # "(" # + self._name - # + ") DeviceTracker Attribute Exists: " - # + str(hasattr(self, "_devicetracker_id")) - # ) - # _LOGGER.debug( - # "(" - # + self._name - # + ") DeviceTracker Entity: " - # + str(self._hass.states.get(self._devicetracker_id)) - # ) - _LOGGER.debug( - "(" - + self._name - + ") [is_devicetracker_set] DeviceTracker State: " - + str( - self._hass.states.get(self._devicetracker_id).state - if self._hass.states.get(self._devicetracker_id) is not None - else None - ) - ) + # + ") [is_devicetracker_set] DeviceTracker State: " + # + str( + # self._hass.states.get(self._devicetracker_id).state + # if self._hass.states.get(self._devicetracker_id) is not None + # else None + # ) + #) if ( hasattr(self, "_devicetracker_id") @@ -389,36 +449,36 @@ def is_devicetracker_set(self): def tsc_update(self, tscarg2, tsarg3, tsarg4): """Call the do_update function based on the TSC (track state change) event""" if self.is_devicetracker_set(): - _LOGGER.debug( - "(" - + self._name - + ") [TSC Update] Running Update - Devicetracker is set" - ) + # _LOGGER.debug( + # "(" + # + self._name + # + ") [TSC Update] Running Update - Devicetracker is set" + # ) self.do_update("Track State Change") - else: - _LOGGER.debug( - "(" - + self._name - + ") [TSC Update] Not Running Update - Devicetracker is not set" - ) + #else: + # _LOGGER.debug( + # "(" + # + self._name + # + ") [TSC Update] Not Running Update - Devicetracker is not set" + # ) @Throttle(THROTTLE_INTERVAL) async def async_update(self): """Call the do_update function based on scan interval and throttle""" if self.is_devicetracker_set(): - _LOGGER.debug( - "(" - + self._name - + ") [Async Update] Running Update - Devicetracker is set" - ) + # _LOGGER.debug( + # "(" + # + self._name + # + ") [Async Update] Running Update - Devicetracker is set" + # ) await self._hass.async_add_executor_job(self.do_update, "Scan Interval") # self.do_update("Scan Interval") - else: - _LOGGER.debug( - "(" - + self._name - + ") [Async Update] Not Running Update - Devicetracker is not set" - ) + #else: + # _LOGGER.debug( + # "(" + # + self._name + # + ") [Async Update] Not Running Update - Devicetracker is not set" + # ) def haversine(self, lon1, lat1, lon2, lat2): """ @@ -478,6 +538,7 @@ def do_update(self, reason): prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) + _LOGGER.debug(" config_entry: " + str(self._config_entry.data)) if hasattr(self, "entity_id") and self.entity_id is not None: # _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) # _LOGGER.debug( From 80a68d64122b7ca026e074a84b15ff4932b22b19 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 16:54:46 -0400 Subject: [PATCH 265/329] :art: Format Python code with isort & Black Code Formatter (#120) --- custom_components/places/sensor.py | 98 ++++++++++++++++-------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 49d2ce83..8773b61c 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -28,18 +28,19 @@ from homeassistant import config_entries from homeassistant import core from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_FRIENDLY_NAME from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import CONF_ZONE from homeassistant.const import Platform +from homeassistant.helpers import device_registry +from homeassistant.helpers import entity_registry from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle from homeassistant.util.location import distance -from homeassistant.helpers import device_registry, entity_registry -from homeassistant.const import ATTR_FRIENDLY_NAME from requests import get from .const import ATTR_CITY @@ -144,6 +145,7 @@ def _exclude_by_entity_registry( ) ) + # From: core/homeassistant/components/homekit/config_flow.py def _async_get_matching_entities( hass: core.HomeAssistant, @@ -164,6 +166,7 @@ def _async_get_matching_entities( ) } + async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, @@ -174,38 +177,45 @@ async def async_setup_entry( config = hass.data[DOMAIN][config_entry.entry_id] unique_id = config_entry.entry_id name = config.get(CONF_NAME) - #_LOGGER.debug("[async_setup_entry] config: " + str(config)) - #_LOGGER.debug("[async_setup_entry] hass: " + str(hass)) - #_LOGGER.debug("[async_setup_entry] hass data type: " + str(type(hass.data))) - #_LOGGER.debug("[async_setup_entry] hass data: " + str(hass.data)) - #_LOGGER.debug("[async_setup_entry] hass states: " + str(hass.states)) - #_LOGGER.debug("[async_setup_entry] hass states entity_ids: " + str(hass.states.async_entity_ids())) - _LOGGER.debug("[async_setup_entry] hass states device_tracker entity_ids: " + str(hass.states.async_entity_ids('device_tracker'))) - _LOGGER.debug("[async_setup_entry] hass states zone entity_ids: " + str(hass.states.async_entity_ids('zone'))) - #_LOGGER.debug("[async_setup_entry] hass components: " + str(hass.components)) - #_LOGGER.debug("[async_setup_entry] hass components type: " + str(type(hass.components))) - #_LOGGER.debug("[async_setup_entry] hass components device_tracker: " + str(hass.components.device_tracker)) - #_LOGGER.debug("[async_setup_entry] hass components zone: " + str(hass.components.zone)) - - - #compdict = [ s.component for s in hass.states.async_all() ] - #_LOGGER.debug("[async_setup_entry] hass components full list: " + str(compdict)) - #compdict = list(dict.fromkeys(compdict)) - #cnt = len(domains) - #compdict.sort() - - #compdict = [] - - #for component in hass.components: + # _LOGGER.debug("[async_setup_entry] config: " + str(config)) + # _LOGGER.debug("[async_setup_entry] hass: " + str(hass)) + # _LOGGER.debug("[async_setup_entry] hass data type: " + str(type(hass.data))) + # _LOGGER.debug("[async_setup_entry] hass data: " + str(hass.data)) + # _LOGGER.debug("[async_setup_entry] hass states: " + str(hass.states)) + # _LOGGER.debug("[async_setup_entry] hass states entity_ids: " + str(hass.states.async_entity_ids())) + _LOGGER.debug( + "[async_setup_entry] hass states device_tracker entity_ids: " + + str(hass.states.async_entity_ids("device_tracker")) + ) + _LOGGER.debug( + "[async_setup_entry] hass states zone entity_ids: " + + str(hass.states.async_entity_ids("zone")) + ) + # _LOGGER.debug("[async_setup_entry] hass components: " + str(hass.components)) + # _LOGGER.debug("[async_setup_entry] hass components type: " + str(type(hass.components))) + # _LOGGER.debug("[async_setup_entry] hass components device_tracker: " + str(hass.components.device_tracker)) + # _LOGGER.debug("[async_setup_entry] hass components zone: " + str(hass.components.zone)) + + # compdict = [ s.component for s in hass.states.async_all() ] + # _LOGGER.debug("[async_setup_entry] hass components full list: " + str(compdict)) + # compdict = list(dict.fromkeys(compdict)) + # cnt = len(domains) + # compdict.sort() + + # compdict = [] + + # for component in hass.components: # if component.count('.') == 0 and component not in compdict: # compdict[component] = [] # if component.count('.') == 1: # domain, subdomain = component.split('.') # compdict[domain].append(subdomain) - # - #_LOGGER.debug("[async_setup_entry] hass components domains list: " + str(compdict)) + # + # _LOGGER.debug("[async_setup_entry] hass components domains list: " + str(compdict)) - async_add_entities([Places(hass, config, config_entry, name, unique_id)], update_before_add=True) + async_add_entities( + [Places(hass, config, config_entry, name, unique_id)], update_before_add=True + ) class Places(Entity): @@ -214,8 +224,8 @@ class Places(Entity): def __init__(self, hass, config, config_entry, name, unique_id): """Initialize the sensor.""" _LOGGER.debug("[Init] New places sensor: " + str(name)) - #_LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) - #_LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) + # _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) + # _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor Type: " + str(type(hass.data[TRACKING_DOMAIN]))) # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor: " + list(hass.data[TRACKING_DOMAIN])) @@ -426,7 +436,7 @@ def extra_state_attributes(self): return return_attr def is_devicetracker_set(self): - #_LOGGER.debug( + # _LOGGER.debug( # "(" # + self._name # + ") [is_devicetracker_set] DeviceTracker State: " @@ -435,7 +445,7 @@ def is_devicetracker_set(self): # if self._hass.states.get(self._devicetracker_id) is not None # else None # ) - #) + # ) if ( hasattr(self, "_devicetracker_id") @@ -449,13 +459,13 @@ def is_devicetracker_set(self): def tsc_update(self, tscarg2, tsarg3, tsarg4): """Call the do_update function based on the TSC (track state change) event""" if self.is_devicetracker_set(): - # _LOGGER.debug( - # "(" - # + self._name - # + ") [TSC Update] Running Update - Devicetracker is set" - # ) + # _LOGGER.debug( + # "(" + # + self._name + # + ") [TSC Update] Running Update - Devicetracker is set" + # ) self.do_update("Track State Change") - #else: + # else: # _LOGGER.debug( # "(" # + self._name @@ -466,14 +476,14 @@ def tsc_update(self, tscarg2, tsarg3, tsarg4): async def async_update(self): """Call the do_update function based on scan interval and throttle""" if self.is_devicetracker_set(): - # _LOGGER.debug( - # "(" - # + self._name - # + ") [Async Update] Running Update - Devicetracker is set" - # ) + # _LOGGER.debug( + # "(" + # + self._name + # + ") [Async Update] Running Update - Devicetracker is set" + # ) await self._hass.async_add_executor_job(self.do_update, "Scan Interval") # self.do_update("Scan Interval") - #else: + # else: # _LOGGER.debug( # "(" # + self._name From e62ad91e82d5fe0e78436224ca9624f943076366 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 18:42:30 -0400 Subject: [PATCH 266/329] Getting closer --- custom_components/places/config_flow.py | 20 ++++---- custom_components/places/const.py | 7 +++ custom_components/places/sensor.py | 62 ++----------------------- 3 files changed, 22 insertions(+), 67 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 7c2132cf..600a647b 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -23,6 +23,10 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_OPTION from .const import DOMAIN # pylint:disable=unused-import +from .const import TRACKING_DOMAIN +from .const import HOME_LOCATION_DOMAIN + +from homeassistant.helpers import selector _LOGGER = logging.getLogger(__name__) MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] @@ -37,18 +41,15 @@ DATA_SCHEMA = vol.Schema( { vol.Required(CONF_NAME): str, - vol.Required(CONF_DEVICETRACKER_ID): str, + vol.Required(CONF_DEVICETRACKER_ID): selector.EntitySelector(selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN)), vol.Optional(CONF_API_KEY): str, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): str, - vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): str, - vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): vol.In( - MAP_PROVIDER_OPTIONS - ), - vol.Optional(CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM)): vol.All( - vol.Coerce(int), vol.Range(min=1, max=20) - ), + vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): selector.EntitySelector(selector.SingleEntitySelectorConfig(domain=HOME_LOCATION_DOMAIN)), + vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): selector.SelectSelector(selector.SelectSelectorConfig(options=MAP_PROVIDER_OPTIONS, multiple=False, custom_value=False, mode=selector.SelectSelectorMode.DROPDOWN)), + #vol.In(MAP_PROVIDER_OPTIONS), + vol.Optional(CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM)): selector.NumberSelector(selector.NumberSelectorConfig(min=1, max=20, mode=selector.NumberSelectorMode.BOX)), vol.Optional(CONF_LANGUAGE): str, - vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): bool, + vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): selector.BooleanSelector(selector.BooleanSelectorConfig()), } ) @@ -112,6 +113,7 @@ async def async_step_user(self, user_input=None): # `validate_input` above. errors = {} if user_input is not None: + _LOGGER.debug("[config_flow] user_input: " + str(user_input)) try: info = await validate_input(self.hass, user_input) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 37c64ea2..0fb9f8f8 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -1,3 +1,6 @@ +from homeassistant.const import CONF_ZONE +from homeassistant.const import Platform + DOMAIN = "placesv2dev" # Defaults @@ -11,6 +14,10 @@ DEFAULT_LANGUAGE = "en" DEFAULT_EXTENDED_ATTR = False +# Settings +TRACKING_DOMAIN = str(Platform.DEVICE_TRACKER) +HOME_LOCATION_DOMAIN = CONF_ZONE + # Config CONF_DEVICETRACKER_ID = "devicetracker_id" CONF_HOME_ZONE = "home_zone" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8773b61c..445fc91a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -33,9 +33,6 @@ from homeassistant.const import CONF_FRIENDLY_NAME from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL -from homeassistant.const import CONF_ZONE -from homeassistant.const import Platform -from homeassistant.helpers import device_registry from homeassistant.helpers import entity_registry from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change @@ -99,20 +96,13 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_OPTION from .const import DOMAIN +from .const import TRACKING_DOMAIN +from .const import HOME_LOCATION_DOMAIN THROTTLE_INTERVAL = timedelta(seconds=600) -TRACKING_DOMAIN = str(Platform.DEVICE_TRACKER) -HOME_LOCATION_DOMAIN = CONF_ZONE SCAN_INTERVAL = timedelta(seconds=30) _LOGGER = logging.getLogger(__name__) -#### -full_domain_list = [] -zone_list = [] -device_tracker_list = [] -my_entity_id = None -my_entity_domain = None - PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_DEVICETRACKER_ID): cv.string, @@ -177,41 +167,6 @@ async def async_setup_entry( config = hass.data[DOMAIN][config_entry.entry_id] unique_id = config_entry.entry_id name = config.get(CONF_NAME) - # _LOGGER.debug("[async_setup_entry] config: " + str(config)) - # _LOGGER.debug("[async_setup_entry] hass: " + str(hass)) - # _LOGGER.debug("[async_setup_entry] hass data type: " + str(type(hass.data))) - # _LOGGER.debug("[async_setup_entry] hass data: " + str(hass.data)) - # _LOGGER.debug("[async_setup_entry] hass states: " + str(hass.states)) - # _LOGGER.debug("[async_setup_entry] hass states entity_ids: " + str(hass.states.async_entity_ids())) - _LOGGER.debug( - "[async_setup_entry] hass states device_tracker entity_ids: " - + str(hass.states.async_entity_ids("device_tracker")) - ) - _LOGGER.debug( - "[async_setup_entry] hass states zone entity_ids: " - + str(hass.states.async_entity_ids("zone")) - ) - # _LOGGER.debug("[async_setup_entry] hass components: " + str(hass.components)) - # _LOGGER.debug("[async_setup_entry] hass components type: " + str(type(hass.components))) - # _LOGGER.debug("[async_setup_entry] hass components device_tracker: " + str(hass.components.device_tracker)) - # _LOGGER.debug("[async_setup_entry] hass components zone: " + str(hass.components.zone)) - - # compdict = [ s.component for s in hass.states.async_all() ] - # _LOGGER.debug("[async_setup_entry] hass components full list: " + str(compdict)) - # compdict = list(dict.fromkeys(compdict)) - # cnt = len(domains) - # compdict.sort() - - # compdict = [] - - # for component in hass.components: - # if component.count('.') == 0 and component not in compdict: - # compdict[component] = [] - # if component.count('.') == 1: - # domain, subdomain = component.split('.') - # compdict[domain].append(subdomain) - # - # _LOGGER.debug("[async_setup_entry] hass components domains list: " + str(compdict)) async_add_entities( [Places(hass, config, config_entry, name, unique_id)], update_before_add=True @@ -224,10 +179,6 @@ class Places(Entity): def __init__(self, hass, config, config_entry, name, unique_id): """Initialize the sensor.""" _LOGGER.debug("[Init] New places sensor: " + str(name)) - # _LOGGER.debug("(" + str(name) + ") [Init] unique_id: " + str(unique_id)) - # _LOGGER.debug("(" + str(name) + ") [Init] config: " + str(config)) - # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor Type: " + str(type(hass.data[TRACKING_DOMAIN]))) - # _LOGGER.debug("(" + str(name) + ") [Init] Hass Sensor: " + list(hass.data[TRACKING_DOMAIN])) self._config = config self._config_entry = config_entry @@ -548,7 +499,7 @@ def do_update(self, reason): prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) - _LOGGER.debug(" config_entry: " + str(self._config_entry.data)) + #_LOGGER.debug(" config_entry: " + str(self._config_entry.data)) if hasattr(self, "entity_id") and self.entity_id is not None: # _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) # _LOGGER.debug( @@ -612,11 +563,6 @@ def do_update(self, reason): ) _LOGGER.debug("(" + self._name + ") Previous State: " + str(previous_state)) - # Can remove this 'if' now since we are checking before calling do_update - # if ( - # hasattr(self, "_devicetracker_id") - # and self._hass.states.get(self._devicetracker_id) is not None - # ): now = datetime.now() old_latitude = str(self._latitude) if not self.is_float(old_latitude): @@ -686,7 +632,7 @@ def do_update(self, reason): + "&z=" + str(self._map_zoom) ) - # maplink_google = 'https://www.google.com/maps/dir/?api=1&origin=' + current_location + '&destination=' + home_location + '&travelmode=driving&layer=traffic' + maplink_google = ( "https://www.google.com/maps/search/?api=1&basemap=roadmap&layer=traffic&query=" + str(current_location) From fd0ef40c28f7ef255d669aaf5e0884a847e55d47 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 18:45:01 -0400 Subject: [PATCH 267/329] Update config_flow.py --- custom_components/places/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 600a647b..e51c11ba 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -113,7 +113,7 @@ async def async_step_user(self, user_input=None): # `validate_input` above. errors = {} if user_input is not None: - _LOGGER.debug("[config_flow] user_input: " + str(user_input)) + _LOGGER.debug("[config_flow] user_input: " + str(user_input)) try: info = await validate_input(self.hass, user_input) From 95e11068fa8c9821552e83c359b621b7391d22b4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 18:45:54 -0400 Subject: [PATCH 268/329] :art: Format Python code with isort & Black Code Formatter (#121) --- custom_components/places/config_flow.py | 40 +++++++++++++++++++------ custom_components/places/sensor.py | 4 +-- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index e51c11ba..c50036fd 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -9,6 +9,7 @@ from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME +from homeassistant.helpers import selector from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR @@ -23,10 +24,8 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_OPTION from .const import DOMAIN # pylint:disable=unused-import -from .const import TRACKING_DOMAIN from .const import HOME_LOCATION_DOMAIN - -from homeassistant.helpers import selector +from .const import TRACKING_DOMAIN _LOGGER = logging.getLogger(__name__) MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] @@ -41,15 +40,38 @@ DATA_SCHEMA = vol.Schema( { vol.Required(CONF_NAME): str, - vol.Required(CONF_DEVICETRACKER_ID): selector.EntitySelector(selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN)), + vol.Required(CONF_DEVICETRACKER_ID): selector.EntitySelector( + selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) + ), vol.Optional(CONF_API_KEY): str, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): str, - vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): selector.EntitySelector(selector.SingleEntitySelectorConfig(domain=HOME_LOCATION_DOMAIN)), - vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): selector.SelectSelector(selector.SelectSelectorConfig(options=MAP_PROVIDER_OPTIONS, multiple=False, custom_value=False, mode=selector.SelectSelectorMode.DROPDOWN)), - #vol.In(MAP_PROVIDER_OPTIONS), - vol.Optional(CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM)): selector.NumberSelector(selector.NumberSelectorConfig(min=1, max=20, mode=selector.NumberSelectorMode.BOX)), + vol.Optional( + CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE + ): selector.EntitySelector( + selector.SingleEntitySelectorConfig(domain=HOME_LOCATION_DOMAIN) + ), + vol.Optional( + CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER + ): selector.SelectSelector( + selector.SelectSelectorConfig( + options=MAP_PROVIDER_OPTIONS, + multiple=False, + custom_value=False, + mode=selector.SelectSelectorMode.DROPDOWN, + ) + ), + # vol.In(MAP_PROVIDER_OPTIONS), + vol.Optional( + CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM) + ): selector.NumberSelector( + selector.NumberSelectorConfig( + min=1, max=20, mode=selector.NumberSelectorMode.BOX + ) + ), vol.Optional(CONF_LANGUAGE): str, - vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): selector.BooleanSelector(selector.BooleanSelectorConfig()), + vol.Optional( + CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR + ): selector.BooleanSelector(selector.BooleanSelectorConfig()), } ) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 445fc91a..6c900bb6 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -96,8 +96,8 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_OPTION from .const import DOMAIN -from .const import TRACKING_DOMAIN from .const import HOME_LOCATION_DOMAIN +from .const import TRACKING_DOMAIN THROTTLE_INTERVAL = timedelta(seconds=600) SCAN_INTERVAL = timedelta(seconds=30) @@ -499,7 +499,7 @@ def do_update(self, reason): prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) - #_LOGGER.debug(" config_entry: " + str(self._config_entry.data)) + # _LOGGER.debug(" config_entry: " + str(self._config_entry.data)) if hasattr(self, "entity_id") and self.entity_id is not None: # _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) # _LOGGER.debug( From fbc3c79a9d69fd039b5c21d54a3b5981464781db Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 19:11:08 -0400 Subject: [PATCH 269/329] Config Flow Selectors --- custom_components/places/config_flow.py | 13 ++++++-- custom_components/places/sensor.py | 41 ------------------------- 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index c50036fd..4b2496a6 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -29,6 +29,7 @@ _LOGGER = logging.getLogger(__name__) MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] +STATE_OPTIONS = ["zone, place", "formatted_place", "zone_name, place"] # Note the input displayed to the user will be translated. See the # translations/.json file and strings.json. See here for further information: @@ -44,7 +45,14 @@ selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) ), vol.Optional(CONF_API_KEY): str, - vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): str, + vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): selector.SelectSelector( + selector.SelectSelectorConfig( + options=MAP_PROVIDER_OPTIONS, + multiple=False, + custom_value=True, + mode=selector.SelectSelectorMode.DROPDOWN, + ) + ), vol.Optional( CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE ): selector.EntitySelector( @@ -60,7 +68,6 @@ mode=selector.SelectSelectorMode.DROPDOWN, ) ), - # vol.In(MAP_PROVIDER_OPTIONS), vol.Optional( CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM) ): selector.NumberSelector( @@ -82,7 +89,7 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] Data has the keys from DATA_SCHEMA with values provided by the user. """ # Validate the data can be used to set up a connection. - + _LOGGER.debug("[config_flow validate_input] data: " + str(data)) # This is a simple example to show an error in the UI for a short hostname # The exceptions are defined at the end of this file, and are used in the # `async_step_user` method below. diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6c900bb6..3bec0abd 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -96,8 +96,6 @@ from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_OPTION from .const import DOMAIN -from .const import HOME_LOCATION_DOMAIN -from .const import TRACKING_DOMAIN THROTTLE_INTERVAL = timedelta(seconds=600) SCAN_INTERVAL = timedelta(seconds=30) @@ -118,45 +116,6 @@ } ) - -# From: core/homeassistant/components/homekit/config_flow.py -def _exclude_by_entity_registry( - ent_reg: entity_registry.EntityRegistry, - entity_id: str, - include_entity_category: bool, - include_hidden: bool, -) -> bool: - """Filter out hidden entities and ones with entity category (unless specified).""" - return bool( - (entry := ent_reg.async_get(entity_id)) - and ( - (not include_hidden and entry.hidden_by is not None) - or (not include_entity_category and entry.entity_category is not None) - ) - ) - - -# From: core/homeassistant/components/homekit/config_flow.py -def _async_get_matching_entities( - hass: core.HomeAssistant, - domains: list[str] | None = None, - include_entity_category: bool = False, - include_hidden: bool = False, -) -> dict[str, str]: - """Fetch all entities or entities in the given domains.""" - ent_reg = entity_registry.async_get(hass) - return { - state.entity_id: f"{state.attributes.get(ATTR_FRIENDLY_NAME, state.entity_id)} ({state.entity_id})" - for state in sorted( - hass.states.async_all(domains and set(domains)), - key=lambda item: item.entity_id, - ) - if not _exclude_by_entity_registry( - ent_reg, state.entity_id, include_entity_category, include_hidden - ) - } - - async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, From 4ff78a08d60ae4e6ef0da31b0f86e4d41739e24e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 19:12:07 -0400 Subject: [PATCH 270/329] :art: Format Python code with isort & Black Code Formatter (#122) --- custom_components/places/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 3bec0abd..16e9a299 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -116,6 +116,7 @@ } ) + async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, From c243aea1ef64a500abdb24fbf0547c9d0732cf19 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 19:15:51 -0400 Subject: [PATCH 271/329] Update config_flow.py --- custom_components/places/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 4b2496a6..b4afcd12 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -47,7 +47,7 @@ vol.Optional(CONF_API_KEY): str, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): selector.SelectSelector( selector.SelectSelectorConfig( - options=MAP_PROVIDER_OPTIONS, + options=STATE_OPTIONS, multiple=False, custom_value=True, mode=selector.SelectSelectorMode.DROPDOWN, From 00d1b50bdde18a329eb0ec0c5badbac8baaf25e6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 19:17:56 -0400 Subject: [PATCH 272/329] Update sensor.py --- custom_components/places/sensor.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 16e9a299..e7ac6bc7 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -30,10 +30,8 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.const import CONF_API_KEY -from homeassistant.const import CONF_FRIENDLY_NAME from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL -from homeassistant.helpers import entity_registry from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle @@ -469,11 +467,11 @@ def do_update(self, reason): # + str(self._hass.states.get(str(self.entity_id))) # ) if self._hass.states.get(str(self.entity_id)).attributes.get( - CONF_FRIENDLY_NAME + ATTR_FRIENDLY_NAME ) is not None and self._name != self._hass.states.get( str(self.entity_id) ).attributes.get( - CONF_FRIENDLY_NAME + ATTR_FRIENDLY_NAME ): _LOGGER.debug( "(" @@ -481,12 +479,12 @@ def do_update(self, reason): + ") Updating Name to: " + str( self._hass.states.get(str(self.entity_id)).attributes.get( - CONF_FRIENDLY_NAME + ATTR_FRIENDLY_NAME ) ) ) self._name = self._hass.states.get(str(self.entity_id)).attributes.get( - CONF_FRIENDLY_NAME + ATTR_FRIENDLY_NAME ) if self._name != self._hass.data[DOMAIN][self._unique_id][CONF_NAME]: _LOGGER.debug( From 25eefc91c9040c40367aa01740b488d7ec2d7bfc Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 20:18:12 -0400 Subject: [PATCH 273/329] Refining --- custom_components/places/config_flow.py | 6 ++++-- custom_components/places/sensor.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index b4afcd12..a02ca51b 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -90,6 +90,8 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] """ # Validate the data can be used to set up a connection. _LOGGER.debug("[config_flow validate_input] data: " + str(data)) + #if hasattr(data,CONF_MAP_ZOOM) and data[CONF_MAP_ZOOM] is not None: + # data[CONF_MAP_ZOOM] = int(data[CONF_MAP_ZOOM]) # This is a simple example to show an error in the UI for a short hostname # The exceptions are defined at the end of this file, and are used in the # `async_step_user` method below. @@ -142,10 +144,10 @@ async def async_step_user(self, user_input=None): # `validate_input` above. errors = {} if user_input is not None: - _LOGGER.debug("[config_flow] user_input: " + str(user_input)) + try: info = await validate_input(self.hass, user_input) - + _LOGGER.debug("[config_flow] user_input: " + str(user_input)) return self.async_create_entry(title=info["title"], data=user_input) except CannotConnect: errors["base"] = "cannot_connect" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e7ac6bc7..d5ee6e3d 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -150,7 +150,7 @@ def __init__(self, hass, config, config_entry, name, unique_id): self._map_provider = config.setdefault( CONF_MAP_PROVIDER, DEFAULT_MAP_PROVIDER ).lower() - self._map_zoom = config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM) + self._map_zoom = int(config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM)) self._language = config.setdefault(CONF_LANGUAGE, DEFAULT_LANGUAGE).lower() self._language.replace(" ", "") self._extended_attr = config.setdefault( From 924c7a667d77c2df58621d878a45fbb13b6dd781 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 20:19:14 -0400 Subject: [PATCH 274/329] :art: Format Python code with isort & Black Code Formatter (#123) --- custom_components/places/config_flow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index a02ca51b..b9114c4f 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -90,7 +90,7 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] """ # Validate the data can be used to set up a connection. _LOGGER.debug("[config_flow validate_input] data: " + str(data)) - #if hasattr(data,CONF_MAP_ZOOM) and data[CONF_MAP_ZOOM] is not None: + # if hasattr(data,CONF_MAP_ZOOM) and data[CONF_MAP_ZOOM] is not None: # data[CONF_MAP_ZOOM] = int(data[CONF_MAP_ZOOM]) # This is a simple example to show an error in the UI for a short hostname # The exceptions are defined at the end of this file, and are used in the @@ -144,7 +144,7 @@ async def async_step_user(self, user_input=None): # `validate_input` above. errors = {} if user_input is not None: - + try: info = await validate_input(self.hass, user_input) _LOGGER.debug("[config_flow] user_input: " + str(user_input)) From a13d327888f49bd2cbf8de297e80a3bf60881ce6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 22:40:39 -0400 Subject: [PATCH 275/329] Get YAML Import Working --- custom_components/places/__init__.py | 1 - custom_components/places/config_flow.py | 73 +++++++++++-------------- custom_components/places/sensor.py | 26 ++++++++- 3 files changed, 58 insertions(+), 42 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 4115b22a..a7e5832a 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -18,7 +18,6 @@ # eg and PLATFORMS: list[str] = [Platform.SENSOR] - async def async_setup_entry( hass: core.HomeAssistant, entry: config_entries.ConfigEntry ) -> bool: diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index b9114c4f..63c3ce95 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -10,6 +10,7 @@ from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.helpers import selector +from homeassistant.data_entry_flow import FlowResult from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR @@ -95,28 +96,6 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] # This is a simple example to show an error in the UI for a short hostname # The exceptions are defined at the end of this file, and are used in the # `async_step_user` method below. - ##if len(data["host"]) < 3: - ## raise InvalidHost - - ##hub = Hub(hass, data["host"]) - # The dummy hub provides a `test_connection` method to ensure it's working - # as expected - ##result = await hub.test_connection() - ##if not result: - # If there is an error, raise an exception to notify HA that there was a - # problem. The UI will also show there was a problem - ##raise CannotConnect - - # If your PyPI package is not built with async, pass your methods - # to the executor: - # await hass.async_add_executor_job( - # your_validate_func, data["username"], data["password"] - # ) - - # If you cannot connect: - # throw CannotConnect - # If the authentication is wrong: - # InvalidAuth # Return info that you want to store in the config entry. # "Title" is what is displayed to the user for this hub device @@ -125,7 +104,7 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] return {"title": data[CONF_NAME]} -class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): +class PlacesConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 # Pick one of the available connection classes in homeassistant/config_entries.py @@ -134,7 +113,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): # changes. ##CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH - async def async_step_user(self, user_input=None): + async def async_step_user(self, user_input=None) -> FlowResult: """Handle the initial step.""" # This goes through the steps to take the user through the setup process. # Using this it is possible to update the UI and prompt for additional @@ -149,14 +128,6 @@ async def async_step_user(self, user_input=None): info = await validate_input(self.hass, user_input) _LOGGER.debug("[config_flow] user_input: " + str(user_input)) return self.async_create_entry(title=info["title"], data=user_input) - except CannotConnect: - errors["base"] = "cannot_connect" - except InvalidHost: - # The error string is set here, and should be translated. - # This example does not currently cover translations, see the - # comments on `DATA_SCHEMA` for further details. - # Set the error on the `host` field, not the entire form. - errors["host"] = "cannot_connect" except Exception: # pylint: disable=broad-except _LOGGER.exception("Unexpected exception") errors["base"] = "unknown" @@ -165,11 +136,33 @@ async def async_step_user(self, user_input=None): return self.async_show_form( step_id="user", data_schema=DATA_SCHEMA, errors=errors ) - - -class CannotConnect(exceptions.HomeAssistantError): - """Error to indicate we cannot connect.""" - - -class InvalidHost(exceptions.HomeAssistantError): - """Error to indicate there is an invalid hostname.""" + + # this is run to import the configuration.yaml parameters + async def async_step_import(self, import_config=None) -> FlowResult: + """Import a config entry from configuration.yaml.""" + _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) + + #data = {} + #try: + #for k in import_config: + # if k == CONF_DEVICE: + # # flatten out the structure so the data variable is a simple dictionary + # device_type = import_config.get(CONF_DEVICE) + # if device_type[CONF_DEVICE_TYPE] == "ethernet": + # data[CONF_DEVICE_TYPE] = "ethernet" + # data[CONF_HOST] = device_type[CONF_HOST] + # data[CONF_PORT] = device_type[CONF_PORT] + # elif device_type[CONF_DEVICE_TYPE] == "usb": + # data[CONF_DEVICE_TYPE] = "usb" + # data[CONF_PATH] = device_type[CONF_PATH] + # if CONF_DEVICE_BAUD in device_type: + # data[CONF_DEVICE_BAUD] = device_type[CONF_DEVICE_BAUD] + # else: + # data[CONF_DEVICE_BAUD] = int(9600) + # else: + # data[k] = import_config.get(k) + #except Exception as err: + #_LOGGER.warning("[async_step_import] Import error: " + str(err)) + #return self.async_abort(reason="settings_missing") + + #return await self.async_step_user(import_config) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index d5ee6e3d..dcddf56c 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -114,13 +114,37 @@ } ) +async def async_setup_platform( + hass: HomeAssistant, + config: ConfigType, + async_add_entities: AddEntitiesCallback, + discovery_info: DiscoveryInfoType | None = None, +) -> None: + """Set up places sensor from YAML.""" + + @callback + def schedule_import(_): + """Schedule delayed import after HA is fully started.""" + async_call_later(hass, 10, do_import) + + @callback + def do_import(_): + """Process YAML import.""" + hass.async_create_task( + hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=dict(config) + ) + ) + + hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) + async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, async_add_entities, ) -> None: - """Setup the sensor platform.""" + """Setup the sensor platform with a config_entry (config_flow).""" config = hass.data[DOMAIN][config_entry.entry_id] unique_id = config_entry.entry_id From 9cdbee5dc19d78f20d74bb54d111654cc631bae2 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 22:41:26 -0400 Subject: [PATCH 276/329] :art: Format Python code with isort & Black Code Formatter (#126) --- custom_components/places/__init__.py | 1 + custom_components/places/config_flow.py | 55 +++++++++++++------------ custom_components/places/sensor.py | 5 ++- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index a7e5832a..4115b22a 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -18,6 +18,7 @@ # eg and PLATFORMS: list[str] = [Platform.SENSOR] + async def async_setup_entry( hass: core.HomeAssistant, entry: config_entries.ConfigEntry ) -> bool: diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 63c3ce95..e160083c 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -9,8 +9,8 @@ from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME -from homeassistant.helpers import selector from homeassistant.data_entry_flow import FlowResult +from homeassistant.helpers import selector from .const import CONF_DEVICETRACKER_ID from .const import CONF_EXTENDED_ATTR @@ -136,33 +136,34 @@ async def async_step_user(self, user_input=None) -> FlowResult: return self.async_show_form( step_id="user", data_schema=DATA_SCHEMA, errors=errors ) - - # this is run to import the configuration.yaml parameters + + # this is run to import the configuration.yaml parameters + async def async_step_import(self, import_config=None) -> FlowResult: """Import a config entry from configuration.yaml.""" _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) - #data = {} - #try: - #for k in import_config: - # if k == CONF_DEVICE: - # # flatten out the structure so the data variable is a simple dictionary - # device_type = import_config.get(CONF_DEVICE) - # if device_type[CONF_DEVICE_TYPE] == "ethernet": - # data[CONF_DEVICE_TYPE] = "ethernet" - # data[CONF_HOST] = device_type[CONF_HOST] - # data[CONF_PORT] = device_type[CONF_PORT] - # elif device_type[CONF_DEVICE_TYPE] == "usb": - # data[CONF_DEVICE_TYPE] = "usb" - # data[CONF_PATH] = device_type[CONF_PATH] - # if CONF_DEVICE_BAUD in device_type: - # data[CONF_DEVICE_BAUD] = device_type[CONF_DEVICE_BAUD] - # else: - # data[CONF_DEVICE_BAUD] = int(9600) - # else: - # data[k] = import_config.get(k) - #except Exception as err: - #_LOGGER.warning("[async_step_import] Import error: " + str(err)) - #return self.async_abort(reason="settings_missing") - - #return await self.async_step_user(import_config) + # data = {} + # try: + # for k in import_config: + # if k == CONF_DEVICE: + # # flatten out the structure so the data variable is a simple dictionary + # device_type = import_config.get(CONF_DEVICE) + # if device_type[CONF_DEVICE_TYPE] == "ethernet": + # data[CONF_DEVICE_TYPE] = "ethernet" + # data[CONF_HOST] = device_type[CONF_HOST] + # data[CONF_PORT] = device_type[CONF_PORT] + # elif device_type[CONF_DEVICE_TYPE] == "usb": + # data[CONF_DEVICE_TYPE] = "usb" + # data[CONF_PATH] = device_type[CONF_PATH] + # if CONF_DEVICE_BAUD in device_type: + # data[CONF_DEVICE_BAUD] = device_type[CONF_DEVICE_BAUD] + # else: + # data[CONF_DEVICE_BAUD] = int(9600) + # else: + # data[k] = import_config.get(k) + # except Exception as err: + # _LOGGER.warning("[async_step_import] Import error: " + str(err)) + # return self.async_abort(reason="settings_missing") + + # return await self.async_step_user(import_config) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index dcddf56c..a14b015b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -114,6 +114,7 @@ } ) + async def async_setup_platform( hass: HomeAssistant, config: ConfigType, @@ -132,7 +133,9 @@ def do_import(_): """Process YAML import.""" hass.async_create_task( hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=dict(config) + DOMAIN, + context={"source": config_entries.SOURCE_IMPORT}, + data=dict(config), ) ) From 9b30a2fbc4e05b2ea27f9e60838037c195a1b2f7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 22:49:18 -0400 Subject: [PATCH 277/329] flake8 Fixes --- custom_components/places/config_flow.py | 1 - custom_components/places/sensor.py | 10 +++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index e160083c..89eed83b 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -6,7 +6,6 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant import core -from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.data_entry_flow import FlowResult diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a14b015b..f986d2e5 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -32,10 +32,14 @@ from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.const import CONF_SCAN_INTERVAL +from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change from homeassistant.util import Throttle from homeassistant.util.location import distance +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.event import async_call_later +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from requests import get from .const import ATTR_CITY @@ -116,19 +120,19 @@ async def async_setup_platform( - hass: HomeAssistant, + hass: core.HomeAssistant, config: ConfigType, async_add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up places sensor from YAML.""" - @callback + @core.callback def schedule_import(_): """Schedule delayed import after HA is fully started.""" async_call_later(hass, 10, do_import) - @callback + @core.callback def do_import(_): """Process YAML import.""" hass.async_create_task( From fe279435e9756866cb84a93d5e6b1f69108eabed Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 22:50:16 -0400 Subject: [PATCH 278/329] :art: Format Python code with isort & Black Code Formatter (#127) --- custom_components/places/sensor.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index f986d2e5..a07558e6 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -34,12 +34,13 @@ from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_track_state_change +from homeassistant.helpers.typing import ConfigType +from homeassistant.helpers.typing import DiscoveryInfoType from homeassistant.util import Throttle from homeassistant.util.location import distance -from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_call_later -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from requests import get from .const import ATTR_CITY From 14db6ecb6fb455693a6cba5396aac274cbc9d8e4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 23:18:18 -0400 Subject: [PATCH 279/329] Update config_flow.py --- custom_components/places/config_flow.py | 39 +++++++++---------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 89eed83b..669c15fe 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -140,29 +140,16 @@ async def async_step_user(self, user_input=None) -> FlowResult: async def async_step_import(self, import_config=None) -> FlowResult: """Import a config entry from configuration.yaml.""" - _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) - - # data = {} - # try: - # for k in import_config: - # if k == CONF_DEVICE: - # # flatten out the structure so the data variable is a simple dictionary - # device_type = import_config.get(CONF_DEVICE) - # if device_type[CONF_DEVICE_TYPE] == "ethernet": - # data[CONF_DEVICE_TYPE] = "ethernet" - # data[CONF_HOST] = device_type[CONF_HOST] - # data[CONF_PORT] = device_type[CONF_PORT] - # elif device_type[CONF_DEVICE_TYPE] == "usb": - # data[CONF_DEVICE_TYPE] = "usb" - # data[CONF_PATH] = device_type[CONF_PATH] - # if CONF_DEVICE_BAUD in device_type: - # data[CONF_DEVICE_BAUD] = device_type[CONF_DEVICE_BAUD] - # else: - # data[CONF_DEVICE_BAUD] = int(9600) - # else: - # data[k] = import_config.get(k) - # except Exception as err: - # _LOGGER.warning("[async_step_import] Import error: " + str(err)) - # return self.async_abort(reason="settings_missing") - - # return await self.async_step_user(import_config) + _LOGGER.debug("[async_step_import] initial import_config: " + str(import_config)) + + data = {} + try: + for item in import_config: + if item not in ["platform","scan_interval"]: + data[item] = import_config.get(item) + except Exception as err: + _LOGGER.warning("[async_step_import] Import error: " + str(err)) + return self.async_abort(reason="settings_missing") + _LOGGER.debug("[async_step_import] final import_config: " + str(data)) + + return await self.async_step_user(data) From ec9c60c7637b81b95f4bd01ff208a9eb5972d32a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 23:19:01 -0400 Subject: [PATCH 280/329] :art: Format Python code with isort & Black Code Formatter (#128) --- custom_components/places/config_flow.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 669c15fe..80c18507 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -140,12 +140,14 @@ async def async_step_user(self, user_input=None) -> FlowResult: async def async_step_import(self, import_config=None) -> FlowResult: """Import a config entry from configuration.yaml.""" - _LOGGER.debug("[async_step_import] initial import_config: " + str(import_config)) + _LOGGER.debug( + "[async_step_import] initial import_config: " + str(import_config) + ) data = {} try: for item in import_config: - if item not in ["platform","scan_interval"]: + if item not in ["platform", "scan_interval"]: data[item] = import_config.get(item) except Exception as err: _LOGGER.warning("[async_step_import] Import error: " + str(err)) From 67036621d494eb1cf662275c0cfd8933ae6801fc Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Thu, 15 Sep 2022 23:34:56 -0400 Subject: [PATCH 281/329] Update sensor.py --- custom_components/places/sensor.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a07558e6..6d0b4ccc 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -243,7 +243,6 @@ def __init__(self, hass, config, config_entry, name, unique_id): self._osm_details_dict = None self._wikidata_dict = None - # Check if devicetracker_id was specified correctly _LOGGER.info( "(" + self._name @@ -251,8 +250,6 @@ def __init__(self, hass, config, config_entry, name, unique_id): + self._devicetracker_id ) - # if devicetracker_id.split(".", 1)[0] in TRACKABLE_DOMAINS: - # self._devicetracker_id = devicetracker_id async_track_state_change( hass, self._devicetracker_id, From 1e87b2598012ee86cde0c2b4cff0509f6c5e4d33 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 16:34:44 -0400 Subject: [PATCH 282/329] Prevent duplicates on yaml import --- custom_components/places/config_flow.py | 81 ++++++++++++++++--------- custom_components/places/const.py | 1 + custom_components/places/sensor.py | 40 ++++++++++-- 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 80c18507..6b3f803a 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -1,13 +1,17 @@ from __future__ import annotations +import hashlib import logging from typing import Any import voluptuous as vol from homeassistant import config_entries from homeassistant import core +from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_SCAN_INTERVAL +from homeassistant.const import CONF_PLATFORM from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import selector @@ -18,6 +22,7 @@ from .const import CONF_MAP_PROVIDER from .const import CONF_MAP_ZOOM from .const import CONF_OPTIONS +from .const import CONF_YAML_HASH from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE from .const import DEFAULT_MAP_PROVIDER @@ -88,18 +93,22 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] Data has the keys from DATA_SCHEMA with values provided by the user. """ - # Validate the data can be used to set up a connection. + _LOGGER.debug("[config_flow validate_input] data: " + str(data)) - # if hasattr(data,CONF_MAP_ZOOM) and data[CONF_MAP_ZOOM] is not None: - # data[CONF_MAP_ZOOM] = int(data[CONF_MAP_ZOOM]) - # This is a simple example to show an error in the UI for a short hostname - # The exceptions are defined at the end of this file, and are used in the - # `async_step_user` method below. - - # Return info that you want to store in the config entry. - # "Title" is what is displayed to the user for this hub device - # It is stored internally in HA as part of the device config. - # See `async_step_user` below for how this is used + + # If a YAML Import, use MD5 Hash to see if it aready exists + #if CONF_YAML_HASH in data: + # all_yaml_hashes = [] + # for m in list(hass.data[DOMAIN].values()): + # if CONF_YAML_HASH in m: + # all_yaml_hashes.append(m[CONF_YAML_HASH]) + + #_LOGGER.debug("[config_flow validate_input] importing yaml hash: " + str(data.get(CONF_YAML_HASH))) + #_LOGGER.debug("[config_flow validate_input] existing places data: " + str(hass.data[DOMAIN])) + #_LOGGER.debug("[config_flow validate_input] All yaml hashes: " + str(all_yaml_hashes)) + # if data[CONF_YAML_HASH] in all_yaml_hashes: + # #_LOGGER.debug("[config_flow validate_input] yaml import is duplicate, not importing") + # raise YamlAlreadyImported return {"title": data[CONF_NAME]} @@ -125,10 +134,13 @@ async def async_step_user(self, user_input=None) -> FlowResult: try: info = await validate_input(self.hass, user_input) - _LOGGER.debug("[config_flow] user_input: " + str(user_input)) + _LOGGER.debug("[config_flow async_step_user] user_input: " + str(user_input)) return self.async_create_entry(title=info["title"], data=user_input) - except Exception: # pylint: disable=broad-except - _LOGGER.exception("Unexpected exception") + except YamlAlreadyImported: + # YAML Already imported, ignore + _LOGGER.debug("[config_flow async_step_user] yaml import is duplicate, not importing") + except Exception as err: # pylint: disable=broad-except + _LOGGER.exception("[config_flow async_step_user] Unexpected exception:" + str(err)) errors["base"] = "unknown" # If there is no user input or there were errors, show the form again, including any errors that were found with the input. @@ -136,22 +148,35 @@ async def async_step_user(self, user_input=None) -> FlowResult: step_id="user", data_schema=DATA_SCHEMA, errors=errors ) - # this is run to import the configuration.yaml parameters - + # this is run to import the configuration.yaml parameters\ async def async_step_import(self, import_config=None) -> FlowResult: """Import a config entry from configuration.yaml.""" _LOGGER.debug( "[async_step_import] initial import_config: " + str(import_config) ) - - data = {} - try: - for item in import_config: - if item not in ["platform", "scan_interval"]: - data[item] = import_config.get(item) - except Exception as err: - _LOGGER.warning("[async_step_import] Import error: " + str(err)) - return self.async_abort(reason="settings_missing") - _LOGGER.debug("[async_step_import] final import_config: " + str(data)) - - return await self.async_step_user(data) + + #try: + #import_config.pop(CONF_PLATFORM,1) + #import_config.pop(CONF_SCAN_INTERVAL,1) + + # Generate pseudo-unique id using MD5 and store in config to try to prevent reimporting already imported yaml sensors. + #string_to_hash=import_config.get(CONF_NAME)+import_config.get(CONF_DEVICETRACKER_ID)+import_config.get(CONF_HOME_ZONE) + #_LOGGER.debug( + # "[async_step_import] string_to_hash: " + str(string_to_hash) + #) + #yaml_hash_object = hashlib.md5(string_to_hash.encode()) + #yaml_hash = yaml_hash_object.hexdigest() + #_LOGGER.debug( + # "[async_step_import] yaml_hash: " + str(yaml_hash) + #) + #import_config.setdefault(CONF_YAML_HASH,yaml_hash) + #except Exception as err: + # _LOGGER.warning("[async_step_import] Import error: " + str(err)) + # return self.async_abort(reason="settings_missing") + _LOGGER.debug("[async_step_import] final import_config: " + str(import_config)) + + return await self.async_step_user(import_config) + + +class YamlAlreadyImported(exceptions.HomeAssistantError): + """Error to indicate that YAML sensor is already imported.""" \ No newline at end of file diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 0fb9f8f8..9f07a681 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -26,6 +26,7 @@ CONF_MAP_ZOOM = "map_zoom" CONF_LANGUAGE = "language" CONF_EXTENDED_ATTR = "extended_attr" +CONF_YAML_HASH = "yaml_hash" # Attributes ATTR_OPTIONS = "options" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 6d0b4ccc..2086e04b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -13,6 +13,7 @@ GitHub: /~https://github.com/Snuffy2/places """ +import hashlib import json import logging from datetime import datetime @@ -31,6 +32,7 @@ from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_PLATFORM from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.helpers.entity import Entity @@ -90,6 +92,7 @@ from .const import CONF_LANGUAGE from .const import CONF_MAP_PROVIDER from .const import CONF_MAP_ZOOM +from .const import CONF_YAML_HASH from .const import CONF_OPTIONS from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE @@ -140,12 +143,41 @@ def do_import(_): hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, - data=dict(config), + #data=dict(config), + data=import_config, ) ) - hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) - + import_config = dict(config) + _LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) + import_config.pop(CONF_PLATFORM,1) + import_config.pop(CONF_SCAN_INTERVAL,1) + + # Generate pseudo-unique id using MD5 and store in config to try to prevent reimporting already imported yaml sensors. + string_to_hash=import_config.get(CONF_NAME)+import_config.get(CONF_DEVICETRACKER_ID)+import_config.get(CONF_HOME_ZONE) + #_LOGGER.debug( + # "[async_setup_platform] string_to_hash: " + str(string_to_hash) + #) + yaml_hash_object = hashlib.md5(string_to_hash.encode()) + yaml_hash = yaml_hash_object.hexdigest() + #_LOGGER.debug( + # "[async_setup_platform] yaml_hash: " + str(yaml_hash) + #) + import_config.setdefault(CONF_YAML_HASH,yaml_hash) + _LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) + + all_yaml_hashes = [] + for m in list(hass.data[DOMAIN].values()): + if CONF_YAML_HASH in m: + all_yaml_hashes.append(m[CONF_YAML_HASH]) + + #_LOGGER.debug("[async_setup_platform] New yaml hash: " + str(data.get(CONF_YAML_HASH))) + #_LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) + if import_config[CONF_YAML_HASH] not in all_yaml_hashes: + _LOGGER.debug("[async_setup_platform] New yaml sensor, importing") + hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) + else: + _LOGGER.debug("[async_setup_platform] Yaml sensor already imported, ignoring") async def async_setup_entry( hass: core.HomeAssistant, @@ -495,7 +527,7 @@ def do_update(self, reason): # + ") Entity Data: " # + str(self._hass.states.get(str(self.entity_id))) # ) - if self._hass.states.get(str(self.entity_id)).attributes.get( + if self._hass.states.get(str(self.entity_id)) is not None and self._hass.states.get(str(self.entity_id)).attributes.get( ATTR_FRIENDLY_NAME ) is not None and self._name != self._hass.states.get( str(self.entity_id) From 3b4b4886531c507e8be317397d942ea10588c4fb Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 16:41:16 -0400 Subject: [PATCH 283/329] :art: Format Python code with isort & Black Code Formatter (#129) --- custom_components/places/config_flow.py | 60 ++++++++++++++----------- custom_components/places/sensor.py | 51 ++++++++++++--------- 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 6b3f803a..ddc39711 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -10,8 +10,8 @@ from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME -from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import CONF_PLATFORM +from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import selector @@ -95,17 +95,17 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] """ _LOGGER.debug("[config_flow validate_input] data: " + str(data)) - + # If a YAML Import, use MD5 Hash to see if it aready exists - #if CONF_YAML_HASH in data: + # if CONF_YAML_HASH in data: # all_yaml_hashes = [] # for m in list(hass.data[DOMAIN].values()): # if CONF_YAML_HASH in m: # all_yaml_hashes.append(m[CONF_YAML_HASH]) - #_LOGGER.debug("[config_flow validate_input] importing yaml hash: " + str(data.get(CONF_YAML_HASH))) - #_LOGGER.debug("[config_flow validate_input] existing places data: " + str(hass.data[DOMAIN])) - #_LOGGER.debug("[config_flow validate_input] All yaml hashes: " + str(all_yaml_hashes)) + # _LOGGER.debug("[config_flow validate_input] importing yaml hash: " + str(data.get(CONF_YAML_HASH))) + # _LOGGER.debug("[config_flow validate_input] existing places data: " + str(hass.data[DOMAIN])) + # _LOGGER.debug("[config_flow validate_input] All yaml hashes: " + str(all_yaml_hashes)) # if data[CONF_YAML_HASH] in all_yaml_hashes: # #_LOGGER.debug("[config_flow validate_input] yaml import is duplicate, not importing") # raise YamlAlreadyImported @@ -134,13 +134,19 @@ async def async_step_user(self, user_input=None) -> FlowResult: try: info = await validate_input(self.hass, user_input) - _LOGGER.debug("[config_flow async_step_user] user_input: " + str(user_input)) + _LOGGER.debug( + "[config_flow async_step_user] user_input: " + str(user_input) + ) return self.async_create_entry(title=info["title"], data=user_input) except YamlAlreadyImported: # YAML Already imported, ignore - _LOGGER.debug("[config_flow async_step_user] yaml import is duplicate, not importing") + _LOGGER.debug( + "[config_flow async_step_user] yaml import is duplicate, not importing" + ) except Exception as err: # pylint: disable=broad-except - _LOGGER.exception("[config_flow async_step_user] Unexpected exception:" + str(err)) + _LOGGER.exception( + "[config_flow async_step_user] Unexpected exception:" + str(err) + ) errors["base"] = "unknown" # If there is no user input or there were errors, show the form again, including any errors that were found with the input. @@ -154,23 +160,23 @@ async def async_step_import(self, import_config=None) -> FlowResult: _LOGGER.debug( "[async_step_import] initial import_config: " + str(import_config) ) - - #try: - #import_config.pop(CONF_PLATFORM,1) - #import_config.pop(CONF_SCAN_INTERVAL,1) - - # Generate pseudo-unique id using MD5 and store in config to try to prevent reimporting already imported yaml sensors. - #string_to_hash=import_config.get(CONF_NAME)+import_config.get(CONF_DEVICETRACKER_ID)+import_config.get(CONF_HOME_ZONE) - #_LOGGER.debug( - # "[async_step_import] string_to_hash: " + str(string_to_hash) - #) - #yaml_hash_object = hashlib.md5(string_to_hash.encode()) - #yaml_hash = yaml_hash_object.hexdigest() - #_LOGGER.debug( - # "[async_step_import] yaml_hash: " + str(yaml_hash) - #) - #import_config.setdefault(CONF_YAML_HASH,yaml_hash) - #except Exception as err: + + # try: + # import_config.pop(CONF_PLATFORM,1) + # import_config.pop(CONF_SCAN_INTERVAL,1) + + # Generate pseudo-unique id using MD5 and store in config to try to prevent reimporting already imported yaml sensors. + # string_to_hash=import_config.get(CONF_NAME)+import_config.get(CONF_DEVICETRACKER_ID)+import_config.get(CONF_HOME_ZONE) + # _LOGGER.debug( + # "[async_step_import] string_to_hash: " + str(string_to_hash) + # ) + # yaml_hash_object = hashlib.md5(string_to_hash.encode()) + # yaml_hash = yaml_hash_object.hexdigest() + # _LOGGER.debug( + # "[async_step_import] yaml_hash: " + str(yaml_hash) + # ) + # import_config.setdefault(CONF_YAML_HASH,yaml_hash) + # except Exception as err: # _LOGGER.warning("[async_step_import] Import error: " + str(err)) # return self.async_abort(reason="settings_missing") _LOGGER.debug("[async_step_import] final import_config: " + str(import_config)) @@ -179,4 +185,4 @@ async def async_step_import(self, import_config=None) -> FlowResult: class YamlAlreadyImported(exceptions.HomeAssistantError): - """Error to indicate that YAML sensor is already imported.""" \ No newline at end of file + """Error to indicate that YAML sensor is already imported.""" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 2086e04b..a66f5e3d 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -92,8 +92,8 @@ from .const import CONF_LANGUAGE from .const import CONF_MAP_PROVIDER from .const import CONF_MAP_ZOOM -from .const import CONF_YAML_HASH from .const import CONF_OPTIONS +from .const import CONF_YAML_HASH from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE from .const import DEFAULT_KEY @@ -143,42 +143,47 @@ def do_import(_): hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, - #data=dict(config), + # data=dict(config), data=import_config, ) ) import_config = dict(config) _LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) - import_config.pop(CONF_PLATFORM,1) - import_config.pop(CONF_SCAN_INTERVAL,1) - + import_config.pop(CONF_PLATFORM, 1) + import_config.pop(CONF_SCAN_INTERVAL, 1) + # Generate pseudo-unique id using MD5 and store in config to try to prevent reimporting already imported yaml sensors. - string_to_hash=import_config.get(CONF_NAME)+import_config.get(CONF_DEVICETRACKER_ID)+import_config.get(CONF_HOME_ZONE) - #_LOGGER.debug( + string_to_hash = ( + import_config.get(CONF_NAME) + + import_config.get(CONF_DEVICETRACKER_ID) + + import_config.get(CONF_HOME_ZONE) + ) + # _LOGGER.debug( # "[async_setup_platform] string_to_hash: " + str(string_to_hash) - #) + # ) yaml_hash_object = hashlib.md5(string_to_hash.encode()) yaml_hash = yaml_hash_object.hexdigest() - #_LOGGER.debug( + # _LOGGER.debug( # "[async_setup_platform] yaml_hash: " + str(yaml_hash) - #) - import_config.setdefault(CONF_YAML_HASH,yaml_hash) + # ) + import_config.setdefault(CONF_YAML_HASH, yaml_hash) _LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) - + all_yaml_hashes = [] for m in list(hass.data[DOMAIN].values()): if CONF_YAML_HASH in m: all_yaml_hashes.append(m[CONF_YAML_HASH]) - - #_LOGGER.debug("[async_setup_platform] New yaml hash: " + str(data.get(CONF_YAML_HASH))) - #_LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) + + # _LOGGER.debug("[async_setup_platform] New yaml hash: " + str(data.get(CONF_YAML_HASH))) + # _LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) if import_config[CONF_YAML_HASH] not in all_yaml_hashes: _LOGGER.debug("[async_setup_platform] New yaml sensor, importing") hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) else: _LOGGER.debug("[async_setup_platform] Yaml sensor already imported, ignoring") + async def async_setup_entry( hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry, @@ -527,12 +532,16 @@ def do_update(self, reason): # + ") Entity Data: " # + str(self._hass.states.get(str(self.entity_id))) # ) - if self._hass.states.get(str(self.entity_id)) is not None and self._hass.states.get(str(self.entity_id)).attributes.get( - ATTR_FRIENDLY_NAME - ) is not None and self._name != self._hass.states.get( - str(self.entity_id) - ).attributes.get( - ATTR_FRIENDLY_NAME + if ( + self._hass.states.get(str(self.entity_id)) is not None + and self._hass.states.get(str(self.entity_id)).attributes.get( + ATTR_FRIENDLY_NAME + ) + is not None + and self._name + != self._hass.states.get(str(self.entity_id)).attributes.get( + ATTR_FRIENDLY_NAME + ) ): _LOGGER.debug( "(" From a24d836d47dec1035a3957b1a81e900cf85026cc Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 16:44:34 -0400 Subject: [PATCH 284/329] flake8 fixes --- custom_components/places/config_flow.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index ddc39711..cbd7e3f1 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -1,6 +1,5 @@ from __future__ import annotations -import hashlib import logging from typing import Any @@ -10,8 +9,6 @@ from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME -from homeassistant.const import CONF_PLATFORM -from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import selector @@ -22,7 +19,6 @@ from .const import CONF_MAP_PROVIDER from .const import CONF_MAP_ZOOM from .const import CONF_OPTIONS -from .const import CONF_YAML_HASH from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE from .const import DEFAULT_MAP_PROVIDER From fd64e75e75b870a8fceb99b93b48906f787ef39f Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 16:51:09 -0400 Subject: [PATCH 285/329] Remove old commented code --- custom_components/places/__init__.py | 10 +---- custom_components/places/config_flow.py | 51 +------------------------ 2 files changed, 3 insertions(+), 58 deletions(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 4115b22a..50821427 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -6,12 +6,6 @@ from .const import DOMAIN -# from __future__ import annotations -# from homeassistant.config_entries import ConfigEntry -# from homeassistant.core import HomeAssistant -# from . import hub - - _LOGGER = logging.getLogger(__name__) # List of platforms to support. There should be a matching .py file for each, @@ -23,9 +17,7 @@ async def async_setup_entry( hass: core.HomeAssistant, entry: config_entries.ConfigEntry ) -> bool: """Set up from a config entry.""" - # Store an instance of the "connecting" class that does the work of speaking - # with your actual devices. - ##hass.data.setdefault(DOMAIN, {})[entry.entry_id] = hub.Hub(hass, entry.data["host"]) + _LOGGER.debug("[init async_setup_entry] entry: " + str(entry.data)) hass.data.setdefault(DOMAIN, {}) hass_data = dict(entry.data) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index cbd7e3f1..ec31bc85 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -35,10 +35,7 @@ # Note the input displayed to the user will be translated. See the # translations/.json file and strings.json. See here for further information: # https://developers.home-assistant.io/docs/config_entries_config_flow_handler/#translations -# At the time of writing I found the translations created by the scaffold didn't -# quite work as documented and always gave me the "Lokalise key references" string -# (in square brackets), rather than the actual translated value. I did not attempt to -# figure this out or look further into it. + DATA_SCHEMA = vol.Schema( { vol.Required(CONF_NAME): str, @@ -92,19 +89,6 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] _LOGGER.debug("[config_flow validate_input] data: " + str(data)) - # If a YAML Import, use MD5 Hash to see if it aready exists - # if CONF_YAML_HASH in data: - # all_yaml_hashes = [] - # for m in list(hass.data[DOMAIN].values()): - # if CONF_YAML_HASH in m: - # all_yaml_hashes.append(m[CONF_YAML_HASH]) - - # _LOGGER.debug("[config_flow validate_input] importing yaml hash: " + str(data.get(CONF_YAML_HASH))) - # _LOGGER.debug("[config_flow validate_input] existing places data: " + str(hass.data[DOMAIN])) - # _LOGGER.debug("[config_flow validate_input] All yaml hashes: " + str(all_yaml_hashes)) - # if data[CONF_YAML_HASH] in all_yaml_hashes: - # #_LOGGER.debug("[config_flow validate_input] yaml import is duplicate, not importing") - # raise YamlAlreadyImported return {"title": data[CONF_NAME]} @@ -134,11 +118,6 @@ async def async_step_user(self, user_input=None) -> FlowResult: "[config_flow async_step_user] user_input: " + str(user_input) ) return self.async_create_entry(title=info["title"], data=user_input) - except YamlAlreadyImported: - # YAML Already imported, ignore - _LOGGER.debug( - "[config_flow async_step_user] yaml import is duplicate, not importing" - ) except Exception as err: # pylint: disable=broad-except _LOGGER.exception( "[config_flow async_step_user] Unexpected exception:" + str(err) @@ -153,32 +132,6 @@ async def async_step_user(self, user_input=None) -> FlowResult: # this is run to import the configuration.yaml parameters\ async def async_step_import(self, import_config=None) -> FlowResult: """Import a config entry from configuration.yaml.""" - _LOGGER.debug( - "[async_step_import] initial import_config: " + str(import_config) - ) - - # try: - # import_config.pop(CONF_PLATFORM,1) - # import_config.pop(CONF_SCAN_INTERVAL,1) - - # Generate pseudo-unique id using MD5 and store in config to try to prevent reimporting already imported yaml sensors. - # string_to_hash=import_config.get(CONF_NAME)+import_config.get(CONF_DEVICETRACKER_ID)+import_config.get(CONF_HOME_ZONE) - # _LOGGER.debug( - # "[async_step_import] string_to_hash: " + str(string_to_hash) - # ) - # yaml_hash_object = hashlib.md5(string_to_hash.encode()) - # yaml_hash = yaml_hash_object.hexdigest() - # _LOGGER.debug( - # "[async_step_import] yaml_hash: " + str(yaml_hash) - # ) - # import_config.setdefault(CONF_YAML_HASH,yaml_hash) - # except Exception as err: - # _LOGGER.warning("[async_step_import] Import error: " + str(err)) - # return self.async_abort(reason="settings_missing") - _LOGGER.debug("[async_step_import] final import_config: " + str(import_config)) + _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) return await self.async_step_user(import_config) - - -class YamlAlreadyImported(exceptions.HomeAssistantError): - """Error to indicate that YAML sensor is already imported.""" From 492e8368382dac1c8c74ad025afeec539bbec2b6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 19:13:34 -0400 Subject: [PATCH 286/329] Create Repair Issue for YAML --- custom_components/places/config_flow.py | 1 - custom_components/places/sensor.py | 13 ++++++++++++- custom_components/places/strings.json | 7 +++++++ custom_components/places/translations/en.json | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index ec31bc85..096eae0a 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -6,7 +6,6 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant import core -from homeassistant import exceptions from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_NAME from homeassistant.data_entry_flow import FlowResult diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a66f5e3d..df315ab8 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -39,6 +39,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_track_state_change +from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import DiscoveryInfoType from homeassistant.util import Throttle @@ -152,6 +153,16 @@ def do_import(_): _LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) import_config.pop(CONF_PLATFORM, 1) import_config.pop(CONF_SCAN_INTERVAL, 1) + + if import_config is not None: + async_create_issue( + hass, + DOMAIN, + "deprecated_yaml", + is_fixable=False, + severity=IssueSeverity.WARNING, + translation_key="deprecated_yaml", + ) # Generate pseudo-unique id using MD5 and store in config to try to prevent reimporting already imported yaml sensors. string_to_hash = ( @@ -181,7 +192,7 @@ def do_import(_): _LOGGER.debug("[async_setup_platform] New yaml sensor, importing") hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) else: - _LOGGER.debug("[async_setup_platform] Yaml sensor already imported, ignoring") + _LOGGER.debug("[async_setup_platform] YAML sensor already imported, ignoring") async def async_setup_entry( diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index 8f5a691a..f8da3b3b 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -18,5 +18,12 @@ "description": "Complete the following fields." } } + }, + "issues": { + "deprecated_yaml": { + "title": "Delete the Places YAML configuration", + "description": "Your existing YAML configuration has been imported into the UI automatically.\n\nRemove the Places YAML configuration from your configuration.yaml file and restart Home Assistant to fix this issue." + } } } + diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index 99702b2d..b3b789a7 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -18,5 +18,11 @@ "description": "Complete the following fields." } } + }, + "issues": { + "deprecated_yaml": { + "title": "Delete the Places YAML configuration", + "description": "Your existing YAML configuration has been imported into the UI automatically.\n\nRemove the Places YAML configuration from your configuration.yaml file and restart Home Assistant to fix this issue." + } } } From c9a7c27e760d40d8f02da66be18cba3c516ebb2c Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 19:14:39 -0400 Subject: [PATCH 287/329] :art: Format Python code with isort & Black Code Formatter (#130) --- custom_components/places/sensor.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index df315ab8..251d800a 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -39,7 +39,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_track_state_change -from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue +from homeassistant.helpers.issue_registry import IssueSeverity +from homeassistant.helpers.issue_registry import async_create_issue from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import DiscoveryInfoType from homeassistant.util import Throttle @@ -153,7 +154,7 @@ def do_import(_): _LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) import_config.pop(CONF_PLATFORM, 1) import_config.pop(CONF_SCAN_INTERVAL, 1) - + if import_config is not None: async_create_issue( hass, From beba1509acfbd8c8d495655cce014f7ca6c40de5 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 19:41:09 -0400 Subject: [PATCH 288/329] Update sensor.py --- custom_components/places/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index df315ab8..ee597fde 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -189,10 +189,10 @@ def do_import(_): # _LOGGER.debug("[async_setup_platform] New yaml hash: " + str(data.get(CONF_YAML_HASH))) # _LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) if import_config[CONF_YAML_HASH] not in all_yaml_hashes: - _LOGGER.debug("[async_setup_platform] New yaml sensor, importing") + _LOGGER.debug("[async_setup_platform] New YAML sensor, importing: " + str(import_config.get(CONF_NAME))) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) else: - _LOGGER.debug("[async_setup_platform] YAML sensor already imported, ignoring") + _LOGGER.debug("[async_setup_platform] YAML sensor already imported, ignoring: " + str(import_config.get(CONF_NAME))) async def async_setup_entry( From dbafeb8e24a64c34aea4abefc81124b2c5aa85c7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 19:42:09 -0400 Subject: [PATCH 289/329] :art: Format Python code with isort & Black Code Formatter (#131) --- custom_components/places/sensor.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8b3b5bcc..6612068f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -190,10 +190,16 @@ def do_import(_): # _LOGGER.debug("[async_setup_platform] New yaml hash: " + str(data.get(CONF_YAML_HASH))) # _LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) if import_config[CONF_YAML_HASH] not in all_yaml_hashes: - _LOGGER.debug("[async_setup_platform] New YAML sensor, importing: " + str(import_config.get(CONF_NAME))) + _LOGGER.debug( + "[async_setup_platform] New YAML sensor, importing: " + + str(import_config.get(CONF_NAME)) + ) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) else: - _LOGGER.debug("[async_setup_platform] YAML sensor already imported, ignoring: " + str(import_config.get(CONF_NAME))) + _LOGGER.debug( + "[async_setup_platform] YAML sensor already imported, ignoring: " + + str(import_config.get(CONF_NAME)) + ) async def async_setup_entry( From 3d676a68fa3134aca1b62b19683cfe444587c4a6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 19:43:16 -0400 Subject: [PATCH 290/329] Update sensor.py --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8b3b5bcc..d2340858 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -119,7 +119,7 @@ vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.positive_int, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, - vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + #vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, } ) From c9c7a6c7b5eab0ab3492da7ad40f85af68e0c7ca Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 19:44:09 -0400 Subject: [PATCH 291/329] :art: Format Python code with isort & Black Code Formatter (#132) --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 3b934d63..678142a0 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -119,7 +119,7 @@ vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.positive_int, vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, - #vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + # vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, } ) From b9a6b2471cbd9a17f94d6576df650870d1b0e238 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 20:10:28 -0400 Subject: [PATCH 292/329] Commenting out some debug logging --- custom_components/places/config_flow.py | 4 ++-- custom_components/places/sensor.py | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 096eae0a..9e70f060 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -86,7 +86,7 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] Data has the keys from DATA_SCHEMA with values provided by the user. """ - _LOGGER.debug("[config_flow validate_input] data: " + str(data)) + #_LOGGER.debug("[config_flow validate_input] data: " + str(data)) return {"title": data[CONF_NAME]} @@ -132,5 +132,5 @@ async def async_step_user(self, user_input=None) -> FlowResult: async def async_step_import(self, import_config=None) -> FlowResult: """Import a config entry from configuration.yaml.""" - _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) + #_LOGGER.debug("[async_step_import] import_config: " + str(import_config)) return await self.async_step_user(import_config) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 678142a0..bfa6d7c3 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -145,13 +145,12 @@ def do_import(_): hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, - # data=dict(config), data=import_config, ) ) import_config = dict(config) - _LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) + #_LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) import_config.pop(CONF_PLATFORM, 1) import_config.pop(CONF_SCAN_INTERVAL, 1) @@ -180,7 +179,7 @@ def do_import(_): # "[async_setup_platform] yaml_hash: " + str(yaml_hash) # ) import_config.setdefault(CONF_YAML_HASH, yaml_hash) - _LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) + #_LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) all_yaml_hashes = [] for m in list(hass.data[DOMAIN].values()): @@ -223,7 +222,9 @@ class Places(Entity): def __init__(self, hass, config, config_entry, name, unique_id): """Initialize the sensor.""" - _LOGGER.debug("[Init] New places sensor: " + str(name)) + _LOGGER.debug("(" + + str(name) + + ") [Init] Places sensor: " + str(name)) self._config = config self._config_entry = config_entry @@ -540,8 +541,8 @@ def do_update(self, reason): last_place_name = None prev_last_place_name = None - _LOGGER.info("(" + self._name + ") Calling update due to " + str(reason)) - # _LOGGER.debug(" config_entry: " + str(self._config_entry.data)) + _LOGGER.info("(" + self._name + ") Calling update due to: " + str(reason)) + _LOGGER.debug("(" + self._name + ") config_entry: " + str(self._config_entry.data)) if hasattr(self, "entity_id") and self.entity_id is not None: # _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) # _LOGGER.debug( From ea3337809f5998c044dcda753ed5a5685fd1102d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 20:11:15 -0400 Subject: [PATCH 293/329] :art: Format Python code with isort & Black Code Formatter (#133) --- custom_components/places/config_flow.py | 4 ++-- custom_components/places/sensor.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 9e70f060..01e0ffaf 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -86,7 +86,7 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] Data has the keys from DATA_SCHEMA with values provided by the user. """ - #_LOGGER.debug("[config_flow validate_input] data: " + str(data)) + # _LOGGER.debug("[config_flow validate_input] data: " + str(data)) return {"title": data[CONF_NAME]} @@ -132,5 +132,5 @@ async def async_step_user(self, user_input=None) -> FlowResult: async def async_step_import(self, import_config=None) -> FlowResult: """Import a config entry from configuration.yaml.""" - #_LOGGER.debug("[async_step_import] import_config: " + str(import_config)) + # _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) return await self.async_step_user(import_config) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index bfa6d7c3..362a274f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -150,7 +150,7 @@ def do_import(_): ) import_config = dict(config) - #_LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) + # _LOGGER.debug("[async_setup_platform] initial import_config: " + str(import_config)) import_config.pop(CONF_PLATFORM, 1) import_config.pop(CONF_SCAN_INTERVAL, 1) @@ -179,7 +179,7 @@ def do_import(_): # "[async_setup_platform] yaml_hash: " + str(yaml_hash) # ) import_config.setdefault(CONF_YAML_HASH, yaml_hash) - #_LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) + # _LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) all_yaml_hashes = [] for m in list(hass.data[DOMAIN].values()): @@ -222,9 +222,7 @@ class Places(Entity): def __init__(self, hass, config, config_entry, name, unique_id): """Initialize the sensor.""" - _LOGGER.debug("(" - + str(name) - + ") [Init] Places sensor: " + str(name)) + _LOGGER.debug("(" + str(name) + ") [Init] Places sensor: " + str(name)) self._config = config self._config_entry = config_entry @@ -542,7 +540,9 @@ def do_update(self, reason): prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to: " + str(reason)) - _LOGGER.debug("(" + self._name + ") config_entry: " + str(self._config_entry.data)) + _LOGGER.debug( + "(" + self._name + ") config_entry: " + str(self._config_entry.data) + ) if hasattr(self, "entity_id") and self.entity_id is not None: # _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) # _LOGGER.debug( From 0970e6e148479b05b8d99e8c4c46be77166c87d3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 23:04:16 -0400 Subject: [PATCH 294/329] Update ConfigEntry name with Sensor name change --- custom_components/places/config_flow.py | 6 +---- custom_components/places/sensor.py | 36 +++++-------------------- 2 files changed, 7 insertions(+), 35 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 01e0ffaf..8fc9cbdc 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -94,11 +94,7 @@ async def validate_input(hass: core.HomeAssistant, data: dict) -> dict[str, Any] class PlacesConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 - # Pick one of the available connection classes in homeassistant/config_entries.py - # This tells HA if it should be asking for updates, or it'll be notified of updates - # automatically. This example uses PUSH, as the dummy hub will notify HA of - # changes. - ##CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH + # Connection classes in homeassistant/config_entries.py are now deprecated async def async_step_user(self, user_input=None) -> FlowResult: """Handle the initial step.""" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 362a274f..b8a5046b 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -540,17 +540,8 @@ def do_update(self, reason): prev_last_place_name = None _LOGGER.info("(" + self._name + ") Calling update due to: " + str(reason)) - _LOGGER.debug( - "(" + self._name + ") config_entry: " + str(self._config_entry.data) - ) if hasattr(self, "entity_id") and self.entity_id is not None: # _LOGGER.debug("(" + self._name + ") Entity ID: " + str(self.entity_id)) - # _LOGGER.debug( - # "(" - # + self._name - # + ") Entity Data: " - # + str(self._hass.states.get(str(self.entity_id))) - # ) if ( self._hass.states.get(str(self.entity_id)) is not None and self._hass.states.get(str(self.entity_id)).attributes.get( @@ -565,7 +556,7 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Updating Name to: " + + ") Sensor Name Changed. Updating Name to: " + str( self._hass.states.get(str(self.entity_id)).attributes.get( ATTR_FRIENDLY_NAME @@ -575,34 +566,19 @@ def do_update(self, reason): self._name = self._hass.states.get(str(self.entity_id)).attributes.get( ATTR_FRIENDLY_NAME ) - if self._name != self._hass.data[DOMAIN][self._unique_id][CONF_NAME]: - _LOGGER.debug( - "(" - + self._name - + ") Updating Hass Data Name - Old: " - + str(self._hass.data[DOMAIN][self._unique_id][CONF_NAME]) - ) - self._hass.data[DOMAIN][self._unique_id][CONF_NAME] = self._name - _LOGGER.debug( - "(" - + self._name - + ") Updating Hass Data Name - New: " - + str(self._hass.data[DOMAIN][self._unique_id][CONF_NAME]) - ) - - if self._name != self._config[CONF_NAME]: + self._config[CONF_NAME] = self._name _LOGGER.debug( "(" + self._name - + ") Updating Config Name - Old: " + + ") Updated Config Name: " + str(self._config[CONF_NAME]) ) - self._config[CONF_NAME] = self._name + self._hass.config_entries.async_update_entry(self._config_entry, data=self._config, options=self._config_entry.options) _LOGGER.debug( "(" + self._name - + ") Updating Config Name - New: " - + str(self._config[CONF_NAME]) + + ") Updated ConfigEntry Name: " + + str(self._config_entry.data[CONF_NAME]) ) _LOGGER.info( From f46d863cf288aa41239e4514484925861ceef4ca Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 23:04:59 -0400 Subject: [PATCH 295/329] :art: Format Python code with isort & Black Code Formatter (#134) --- custom_components/places/sensor.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b8a5046b..cc3584d0 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -573,7 +573,11 @@ def do_update(self, reason): + ") Updated Config Name: " + str(self._config[CONF_NAME]) ) - self._hass.config_entries.async_update_entry(self._config_entry, data=self._config, options=self._config_entry.options) + self._hass.config_entries.async_update_entry( + self._config_entry, + data=self._config, + options=self._config_entry.options, + ) _LOGGER.debug( "(" + self._name From 422c99070d1fa77cfa0b57c12ccce913c7b3d197 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 23:15:01 -0400 Subject: [PATCH 296/329] Update __init__.py --- custom_components/places/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 50821427..99d2aefe 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -18,7 +18,7 @@ async def async_setup_entry( ) -> bool: """Set up from a config entry.""" - _LOGGER.debug("[init async_setup_entry] entry: " + str(entry.data)) + #_LOGGER.debug("[init async_setup_entry] entry: " + str(entry.data)) hass.data.setdefault(DOMAIN, {}) hass_data = dict(entry.data) hass.data[DOMAIN][entry.entry_id] = hass_data From ee21006716969fab7e430d675cd1ee2d0653b4ed Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 23:16:29 -0400 Subject: [PATCH 297/329] :art: Format Python code with isort & Black Code Formatter (#135) --- custom_components/places/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/__init__.py b/custom_components/places/__init__.py index 99d2aefe..037f3ff2 100644 --- a/custom_components/places/__init__.py +++ b/custom_components/places/__init__.py @@ -18,7 +18,7 @@ async def async_setup_entry( ) -> bool: """Set up from a config entry.""" - #_LOGGER.debug("[init async_setup_entry] entry: " + str(entry.data)) + # _LOGGER.debug("[init async_setup_entry] entry: " + str(entry.data)) hass.data.setdefault(DOMAIN, {}) hass_data = dict(entry.data) hass.data[DOMAIN][entry.entry_id] = hass_data From c028a74f717284f896ae1153c916a4d5412d84e1 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 23:56:18 -0400 Subject: [PATCH 298/329] Add OptionsFlow --- custom_components/places/config_flow.py | 80 +++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 8fc9cbdc..d1edac28 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -130,3 +130,83 @@ async def async_step_import(self, import_config=None) -> FlowResult: # _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) return await self.async_step_user(import_config) + + + @staticmethod + @core.callback + def async_get_options_flow( + config_entry: config_entries.ConfigEntry, + ) -> PlacesOptionsFlowHandler: + """Options callback for Places.""" + return PlacesOptionsFlowHandler(config_entry) + + +class PlacesOptionsFlowHandler(config_entries.OptionsFlow): + """Config flow options for Places.""" + + def __init__(self, entry: config_entries.ConfigEntry) -> None: + """Initialize Places options flow.""" + self.config_entry = entry + + async def async_step_init(self, user_input=None): + """Manage the options.""" + if user_input is not None: + #if CONF_HOST in self.config_entry.data: + # user_input[CONF_HOST] = self.config_entry.data[CONF_HOST] + #if CONF_EMAIL in self.config_entry.data: + # user_input[CONF_EMAIL] = self.config_entry.data[CONF_EMAIL] + for m in dict(self.config_entry.data).keys(): + user_input.setdefault(m, self.config_entry.data[m]) + self.hass.config_entries.async_update_entry( + self.config_entry, data=user_input, options=self.config_entry.options + ) + return self.async_create_entry(title="", data={}) + #return self.async_create_entry(title=DOMAIN, data=user_input) + + return self.async_show_form( + step_id="opts", + data_schema=vol.Schema( + { + #vol.Required(CONF_NAME): str, + #default=self.config_entry.data[CONF_APP_ID] + vol.Required(CONF_DEVICETRACKER_ID, default=self.config_entry.data[CONF_DEVICETRACKER_ID]): selector.EntitySelector( + selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) + ), + vol.Optional(CONF_API_KEY, default=self.config_entry.data[CONF_APP_KEY]): str, + vol.Optional(CONF_OPTIONS, default=self.config_entry.data[CONF_OPTIONS]): selector.SelectSelector( + selector.SelectSelectorConfig( + options=STATE_OPTIONS, + multiple=False, + custom_value=True, + mode=selector.SelectSelectorMode.DROPDOWN, + ) + ), + vol.Optional( + CONF_HOME_ZONE, default=self.config_entry.data[CONF_HOME_ZONE] + ): selector.EntitySelector( + selector.SingleEntitySelectorConfig(domain=HOME_LOCATION_DOMAIN) + ), + vol.Optional( + CONF_MAP_PROVIDER, default=self.config_entry.data[CONF_MAP_PROVIDER] + ): selector.SelectSelector( + selector.SelectSelectorConfig( + options=MAP_PROVIDER_OPTIONS, + multiple=False, + custom_value=False, + mode=selector.SelectSelectorMode.DROPDOWN, + ) + ), + vol.Optional( + CONF_MAP_ZOOM, default=self.config_entry.data[CONF_MAP_ZOOM] + ): selector.NumberSelector( + selector.NumberSelectorConfig( + min=1, max=20, mode=selector.NumberSelectorMode.BOX + ) + ), + vol.Optional(CONF_LANGUAGE, default=self.config_entry.data[CONF_LANGUAGE]): str, + vol.Optional( + CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR + ): selector.BooleanSelector(selector.BooleanSelectorConfig()), + } + ), + ) From ba51bae9767c2d329b66a3d80e4eeeffee7d2b88 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Fri, 16 Sep 2022 23:57:01 -0400 Subject: [PATCH 299/329] :art: Format Python code with isort & Black Code Formatter (#136) --- custom_components/places/config_flow.py | 31 ++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index d1edac28..d91bfad9 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -131,7 +131,6 @@ async def async_step_import(self, import_config=None) -> FlowResult: # _LOGGER.debug("[async_step_import] import_config: " + str(import_config)) return await self.async_step_user(import_config) - @staticmethod @core.callback def async_get_options_flow( @@ -151,9 +150,9 @@ def __init__(self, entry: config_entries.ConfigEntry) -> None: async def async_step_init(self, user_input=None): """Manage the options.""" if user_input is not None: - #if CONF_HOST in self.config_entry.data: + # if CONF_HOST in self.config_entry.data: # user_input[CONF_HOST] = self.config_entry.data[CONF_HOST] - #if CONF_EMAIL in self.config_entry.data: + # if CONF_EMAIL in self.config_entry.data: # user_input[CONF_EMAIL] = self.config_entry.data[CONF_EMAIL] for m in dict(self.config_entry.data).keys(): user_input.setdefault(m, self.config_entry.data[m]) @@ -161,19 +160,26 @@ async def async_step_init(self, user_input=None): self.config_entry, data=user_input, options=self.config_entry.options ) return self.async_create_entry(title="", data={}) - #return self.async_create_entry(title=DOMAIN, data=user_input) + # return self.async_create_entry(title=DOMAIN, data=user_input) return self.async_show_form( step_id="opts", data_schema=vol.Schema( { - #vol.Required(CONF_NAME): str, - #default=self.config_entry.data[CONF_APP_ID] - vol.Required(CONF_DEVICETRACKER_ID, default=self.config_entry.data[CONF_DEVICETRACKER_ID]): selector.EntitySelector( + # vol.Required(CONF_NAME): str, + # default=self.config_entry.data[CONF_APP_ID] + vol.Required( + CONF_DEVICETRACKER_ID, + default=self.config_entry.data[CONF_DEVICETRACKER_ID], + ): selector.EntitySelector( selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) ), - vol.Optional(CONF_API_KEY, default=self.config_entry.data[CONF_APP_KEY]): str, - vol.Optional(CONF_OPTIONS, default=self.config_entry.data[CONF_OPTIONS]): selector.SelectSelector( + vol.Optional( + CONF_API_KEY, default=self.config_entry.data[CONF_APP_KEY] + ): str, + vol.Optional( + CONF_OPTIONS, default=self.config_entry.data[CONF_OPTIONS] + ): selector.SelectSelector( selector.SelectSelectorConfig( options=STATE_OPTIONS, multiple=False, @@ -187,7 +193,8 @@ async def async_step_init(self, user_input=None): selector.SingleEntitySelectorConfig(domain=HOME_LOCATION_DOMAIN) ), vol.Optional( - CONF_MAP_PROVIDER, default=self.config_entry.data[CONF_MAP_PROVIDER] + CONF_MAP_PROVIDER, + default=self.config_entry.data[CONF_MAP_PROVIDER], ): selector.SelectSelector( selector.SelectSelectorConfig( options=MAP_PROVIDER_OPTIONS, @@ -203,7 +210,9 @@ async def async_step_init(self, user_input=None): min=1, max=20, mode=selector.NumberSelectorMode.BOX ) ), - vol.Optional(CONF_LANGUAGE, default=self.config_entry.data[CONF_LANGUAGE]): str, + vol.Optional( + CONF_LANGUAGE, default=self.config_entry.data[CONF_LANGUAGE] + ): str, vol.Optional( CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR ): selector.BooleanSelector(selector.BooleanSelectorConfig()), From fe00d32aa0458bb2a119189b0762f2f5e2ef266d Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 00:00:36 -0400 Subject: [PATCH 300/329] Update config_flow.py --- custom_components/places/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index d91bfad9..a48986de 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -175,7 +175,7 @@ async def async_step_init(self, user_input=None): selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) ), vol.Optional( - CONF_API_KEY, default=self.config_entry.data[CONF_APP_KEY] + CONF_API_KEY, default=self.config_entry.data[CONF_API_KEY] ): str, vol.Optional( CONF_OPTIONS, default=self.config_entry.data[CONF_OPTIONS] From 4c6b994fd3f88f9d338bb6825034f29b4b3c57d3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 00:40:15 -0400 Subject: [PATCH 301/329] OptionsFlow Fixes --- custom_components/places/config_flow.py | 16 ++++++++++----- custom_components/places/strings.json | 20 ++++++++++++++++++- custom_components/places/translations/en.json | 20 ++++++++++++++++++- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index a48986de..0bbfd611 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -150,12 +150,19 @@ def __init__(self, entry: config_entries.ConfigEntry) -> None: async def async_step_init(self, user_input=None): """Manage the options.""" if user_input is not None: + _LOGGER.debug( + "[options_flow async_step_init] user_input initial: " + str(user_input) + ) # if CONF_HOST in self.config_entry.data: # user_input[CONF_HOST] = self.config_entry.data[CONF_HOST] # if CONF_EMAIL in self.config_entry.data: # user_input[CONF_EMAIL] = self.config_entry.data[CONF_EMAIL] for m in dict(self.config_entry.data).keys(): user_input.setdefault(m, self.config_entry.data[m]) + _LOGGER.debug( + "[options_flow async_step_init] user_input final: " + str(user_input) + ) + self.hass.config_entries.async_update_entry( self.config_entry, data=user_input, options=self.config_entry.options ) @@ -163,14 +170,13 @@ async def async_step_init(self, user_input=None): # return self.async_create_entry(title=DOMAIN, data=user_input) return self.async_show_form( - step_id="opts", + step_id="init", data_schema=vol.Schema( { - # vol.Required(CONF_NAME): str, - # default=self.config_entry.data[CONF_APP_ID] + vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME]): str, vol.Required( CONF_DEVICETRACKER_ID, - default=self.config_entry.data[CONF_DEVICETRACKER_ID], + default=self.config_entry.data[CONF_DEVICETRACKER_ID] ): selector.EntitySelector( selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) ), @@ -214,7 +220,7 @@ async def async_step_init(self, user_input=None): CONF_LANGUAGE, default=self.config_entry.data[CONF_LANGUAGE] ): str, vol.Optional( - CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR + CONF_EXTENDED_ATTR, default=self.config_entry.data[CONF_EXTENDED_ATTR] ): selector.BooleanSelector(selector.BooleanSelectorConfig()), } ), diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index f8da3b3b..b132b2a1 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -1,5 +1,5 @@ { - "title": "Places v2-dev", + "title": "Places", "config": { "step": { "user": { @@ -19,6 +19,24 @@ } } }, + "options": { + "step": { + "init": { + "title": "Change OpenStreetMap Sensor Options", + "data": { + "devicetracker_id": "DeviceTracker ID", + "home_zone": "Home Zone", + "options": "Display Options", + "map_provider": "Map Provider", + "map_zoom": "Map Zoom", + "api_key": "[%key:common::config_flow::data::api_key%]", + "language": "Language", + "extended_attr": "Extended Attributes" + }, + "description": "Complete the following fields." + } + } + }, "issues": { "deprecated_yaml": { "title": "Delete the Places YAML configuration", diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index b3b789a7..466ccce7 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -1,5 +1,5 @@ { - "title": "Places v2-dev", + "title": "Places", "config": { "step": { "user": { @@ -19,6 +19,24 @@ } } }, + "options": { + "step": { + "init": { + "title": "Change OpenStreetMap Sensor Options", + "data": { + "devicetracker_id": "DeviceTracker ID", + "home_zone": "Home Zone", + "options": "Display Options", + "map_provider": "Map Provider", + "map_zoom": "Map Zoom", + "api_key": "Email", + "language": "Language", + "extended_attr": "Extended Attributes" + }, + "description": "Complete the following fields." + } + } + }, "issues": { "deprecated_yaml": { "title": "Delete the Places YAML configuration", From e3cb97453f43ba50947c3431229531456974062a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 10:50:25 -0400 Subject: [PATCH 302/329] Update config_flow.py --- custom_components/places/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 0bbfd611..f032fbcd 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -173,7 +173,7 @@ async def async_step_init(self, user_input=None): step_id="init", data_schema=vol.Schema( { - vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME]): str, + #vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME]): str, vol.Required( CONF_DEVICETRACKER_ID, default=self.config_entry.data[CONF_DEVICETRACKER_ID] From cf4a343376a64b7b9055af547356ef2253ca3aab Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 11:07:54 -0400 Subject: [PATCH 303/329] Remove default key --- custom_components/places/const.py | 1 - custom_components/places/sensor.py | 18 +++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 9f07a681..8a2ed69c 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -8,7 +8,6 @@ DEFAULT_NAME = "placesv2dev" DEFAULT_OPTION = "zone, place" DEFAULT_HOME_ZONE = "zone.home" -DEFAULT_KEY = "no key" DEFAULT_MAP_PROVIDER = "apple" DEFAULT_MAP_ZOOM = 18 DEFAULT_LANGUAGE = "en" diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index cc3584d0..98f687af 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -98,7 +98,6 @@ from .const import CONF_YAML_HASH from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE -from .const import DEFAULT_KEY from .const import DEFAULT_LANGUAGE from .const import DEFAULT_MAP_PROVIDER from .const import DEFAULT_MAP_ZOOM @@ -112,7 +111,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_DEVICETRACKER_ID): cv.string, - vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): cv.string, + vol.Optional(CONF_API_KEY): cv.string, vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): cv.string, vol.Optional(CONF_HOME_ZONE, default=DEFAULT_HOME_ZONE): cv.string, vol.Optional(CONF_NAME): cv.string, @@ -229,7 +228,7 @@ def __init__(self, hass, config, config_entry, name, unique_id): self._hass = hass self._name = name self._unique_id = unique_id - self._api_key = config.setdefault(CONF_API_KEY, DEFAULT_KEY) + self._api_key = config.setdefault(CONF_API_KEY) self._options = config.setdefault(CONF_OPTIONS, DEFAULT_OPTION).lower() self._devicetracker_id = config.get(CONF_DEVICETRACKER_ID).lower() self._home_zone = config.setdefault(CONF_HOME_ZONE, DEFAULT_HOME_ZONE).lower() @@ -856,21 +855,16 @@ def do_update(self, reason): "(" + self._name + ") Map Link generated: " + str(self._map_link) ) - # Change logic and default_key for api-Key osm_url = ( "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" + str(self._latitude) + "&lon=" + str(self._longitude) - + ( - "&accept-language=" + str(self._language) - if self._language != DEFAULT_LANGUAGE - else "" - ) + + "&accept-language=" + str(self._language) + "&addressdetails=1&namedetails=1&zoom=18&limit=1" + ( "&email=" + str(self._api_key) - if self._api_key != DEFAULT_KEY + if self._api_key is not None else "" ) ) @@ -1249,9 +1243,11 @@ def do_update(self, reason): + "&linkedplaces=1&hierarchy=1&group_hierarchy=1&limit=1&format=json" + ( "&email=" + str(self._api_key) - if self._api_key != DEFAULT_KEY + if self._api_key is not None else "" ) + + "&accept-language=" + str(self._language) + ) _LOGGER.info( From 4f9bcadde84c036feb60ec5858c18dfec8daa426 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 11:09:02 -0400 Subject: [PATCH 304/329] Remove default_name --- custom_components/places/const.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 8a2ed69c..d58f8a8d 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -5,7 +5,6 @@ # Defaults DEFAULT_ICON = "mdi:map-marker-circle" -DEFAULT_NAME = "placesv2dev" DEFAULT_OPTION = "zone, place" DEFAULT_HOME_ZONE = "zone.home" DEFAULT_MAP_PROVIDER = "apple" From 767fc978d58db042d99f810ed35c1e177b670e03 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 11:24:36 -0400 Subject: [PATCH 305/329] Update README.md --- README.md | 65 ++++++++++++------------------------------------------- 1 file changed, 14 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index d869e6c5..f5955204 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,14 @@ -_Component to integrate with OpenStreetMap Reverse Geocode (PLACE)_ +_Component to integrate with OpenStreetMap Reverse Geocode_ ## Installation ### Installation via HACS Unless you have a good reason not to, you probably want to install this component via HACS (Home Assistant Community Store) -1. Ensure that [HACS](https://hacs.xyz/) is installed. +1. Ensure that [HACS](https://hacs.xyz/) is installed 1. Navigate to HACS -> Integrations 1. Open the three-dot menu and select 'Custom Repositories' 1. Put '/~https://github.com/Snuffy2/places' into the 'Repository' textbox. @@ -25,17 +25,17 @@ Unless you have a good reason not to, you probably want to install this componen 1. Press 'Add'. 1. Find the Places integration in the HACS integration list and install it 1. Add your configuration -1. Restart Home Assistant. +1. Restart Home Assistant ### Manual Installation You probably do not want to do this! Use the HACS method above unless you have a very good reason why you are installing manually -1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`). -1. If you do not have a `custom_components` directory (folder) there, you need to create it. -1. In the `custom_components` directory (folder) create a new folder called `places`. -1. Download _all_ the files from the `custom_components/places/` directory (folder) in this repository. -1. Place the files you downloaded in the new directory (folder) you created. +1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`) +1. If you do not have a `custom_components` directory (folder) there, you need to create it +1. In the `custom_components` directory (folder) create a new folder called `places` +1. Download _all_ the files from the `custom_components/places/` directory (folder) in this repository +1. Place the files you downloaded in the new directory (folder) you created 1. Add your configuration 1. Restart Home Assistant @@ -47,51 +47,14 @@ custom_components/places/manifest.json custom_components/places/sensor.py ``` -## Example configuration.yaml - -```yaml -sensor places_jim: - - platform: places - name: jim - devicetracker_id: device_tracker.jim_iphone8 - options: zone,place - map_provider: google - map_zoom: 19 - home_zone: zone.jim_home - api_key: !secret email_jim - -sensor places_sharon: - - platform: places - name: sharon - devicetracker_id: device_tracker.sharon_iphone7 - options: zone, place - map_provider: apple - map_zoom: 18 - language: de - home_zone: zone.sharon_home - api_key: !secret email_sharon - -sensor places_aidan: - - platform: places - name: aidan - devicetracker_id: device_tracker.aidan_iphone7plus - options: place - map_provider: google - map_zoom: 17 - language: jp,en - home_zone: zone.aidan_home - api_key: !secret email_aidan -``` - ## Configuration options Key | Type | Required | Description | Default | -- | -- | -- | -- | -- -`platform` | `string` | `True` | `places` | None `devicetracker_id` | `string` | `True` | `entity_id` of the device you wish to track | None -`name` | `string` | `False` | Friendly name of the sensor | `places` -`home_zone` | `string` | `False` | Calculates distance from home and direction of travel if set | `zone.home` -`api_key` | `string` | `False` | OpenStreetMap API key (your email address). | `no key` +`name` | `string` | `True` | Friendly name of the sensor | None +`home_zone` | `string` | `False` | Used to calculate distance from home and direction of travel | `zone.home` +`api_key` | `string` | `False` | OpenStreetMap API key (your email address). | None `map_provider` | `string` | `False` | `google`, `apple`, `osm` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` `language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s). | *Refer to Notes @@ -184,9 +147,9 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat * This component is only useful to those who have device tracking enabled via a mechanism that provides latitude and longitude coordinates (such as Owntracks or iCloud). * The OpenStreetMap database is very flexible with regards to tag_names in their database schema. If you come across a set of coordinates that do not parse properly, you can enable debug messages to see the actual JSON that is returned from the query. * The OpenStreetMap API requests that you include your valid e-mail address in each API call if you are making a large numbers of requests. They say that this information will be kept confidential and only used to contact you in the event of a problem, see their Usage Policy for more details. -* The map link that gets generated for Google and Apple has a push pin marking the users location. Note that when opening the Apple link on a non-Apple device, it will open in Google Maps. -* When no `language` value is given, default language will be location's local language or English. When a comma separated list of languages is provided - the component will attempt to fill each address field in desired languages by order. -* Translations are partial in OpenStreetMap database. For each field, if a translation is missing in first requested language it will be resolved with a language following in the provided list, defaulting to local language if no matching translations were found for the list. +* The map link that gets generated for Google, Apple or OpenStreetMaps has a push pin marking the users location. Note that when opening the Apple link on a non-Apple device, it will open in Google Maps. +* When no `language` value is given, default language will be ~~location's local language or~~ English. ~~When a comma separated list of languages is provided - the component will attempt to fill each address field in desired languages by order.~~ +~~* Translations are partial in OpenStreetMap database. For each field, if a translation is missing in first requested language it will be resolved with a language following in the provided list, defaulting to local language if no matching translations were found for the list.~~ * To enable detailed logging for this component, add the following to your configuration.yaml file ```yaml logger: From 0e0d8845e8d1772dc27b5be577dec1893f184c6e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 11:25:23 -0400 Subject: [PATCH 306/329] :art: Format Python code with isort & Black Code Formatter (#137) --- custom_components/places/config_flow.py | 7 ++++--- custom_components/places/sensor.py | 13 +++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index f032fbcd..1e582af6 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -173,10 +173,10 @@ async def async_step_init(self, user_input=None): step_id="init", data_schema=vol.Schema( { - #vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME]): str, + # vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME]): str, vol.Required( CONF_DEVICETRACKER_ID, - default=self.config_entry.data[CONF_DEVICETRACKER_ID] + default=self.config_entry.data[CONF_DEVICETRACKER_ID], ): selector.EntitySelector( selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) ), @@ -220,7 +220,8 @@ async def async_step_init(self, user_input=None): CONF_LANGUAGE, default=self.config_entry.data[CONF_LANGUAGE] ): str, vol.Optional( - CONF_EXTENDED_ATTR, default=self.config_entry.data[CONF_EXTENDED_ATTR] + CONF_EXTENDED_ATTR, + default=self.config_entry.data[CONF_EXTENDED_ATTR], ): selector.BooleanSelector(selector.BooleanSelectorConfig()), } ), diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 98f687af..b61d2999 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -860,13 +860,10 @@ def do_update(self, reason): + str(self._latitude) + "&lon=" + str(self._longitude) - + "&accept-language=" + str(self._language) + + "&accept-language=" + + str(self._language) + "&addressdetails=1&namedetails=1&zoom=18&limit=1" - + ( - "&email=" + str(self._api_key) - if self._api_key is not None - else "" - ) + + ("&email=" + str(self._api_key) if self._api_key is not None else "") ) osm_decoded = {} @@ -1246,8 +1243,8 @@ def do_update(self, reason): if self._api_key is not None else "" ) - + "&accept-language=" + str(self._language) - + + "&accept-language=" + + str(self._language) ) _LOGGER.info( From 5c4b90d35809d52799ee6638f20c564dd6e504e2 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 14:57:43 -0400 Subject: [PATCH 307/329] Change language to None if not set --- README.md | 6 +++--- custom_components/places/const.py | 1 - custom_components/places/sensor.py | 25 +++++++++++-------------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index f5955204..978a10bd 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Key | Type | Required | Description | Default | `api_key` | `string` | `False` | OpenStreetMap API key (your email address). | None `map_provider` | `string` | `False` | `google`, `apple`, `osm` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` -`language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s). | *Refer to Notes +`language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s), separated by commas.
*Refer to Notes | location's local language `extended_attr` | `boolean` | `False` | Show extended attributes: wikidata_id, osm_dict, osm_details_dict, wikidata_dict *(if they exist)*. Provides many additional attributes for advanced logic. **Warning, will make the attributes very long!** | `False` `options` | `string` | `False` | Display options: `formatted_place` *(exclusive option)*, `driving` *(can be used with formatted_place or other options)*, `zone` or `zone_name`, `place`, `place_name`, `street_number`, `street`, `city`, `county`, `state`, `postal_code`, `country`, `formatted_address`, `do_not_show_not_home` | `zone`, `place` @@ -148,8 +148,8 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat * The OpenStreetMap database is very flexible with regards to tag_names in their database schema. If you come across a set of coordinates that do not parse properly, you can enable debug messages to see the actual JSON that is returned from the query. * The OpenStreetMap API requests that you include your valid e-mail address in each API call if you are making a large numbers of requests. They say that this information will be kept confidential and only used to contact you in the event of a problem, see their Usage Policy for more details. * The map link that gets generated for Google, Apple or OpenStreetMaps has a push pin marking the users location. Note that when opening the Apple link on a non-Apple device, it will open in Google Maps. -* When no `language` value is given, default language will be ~~location's local language or~~ English. ~~When a comma separated list of languages is provided - the component will attempt to fill each address field in desired languages by order.~~ -~~* Translations are partial in OpenStreetMap database. For each field, if a translation is missing in first requested language it will be resolved with a language following in the provided list, defaulting to local language if no matching translations were found for the list.~~ +* When no `language` value is given, default language will be location's local language. When a comma separated list of languages is provided - the component will attempt to fill each address field in desired languages by order. +* Translations are partial in OpenStreetMap database. For each field, if a translation is missing in first requested language it will be resolved with a language following in the provided list, defaulting to local language if no matching translations were found for the list. * To enable detailed logging for this component, add the following to your configuration.yaml file ```yaml logger: diff --git a/custom_components/places/const.py b/custom_components/places/const.py index d58f8a8d..36533106 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -9,7 +9,6 @@ DEFAULT_HOME_ZONE = "zone.home" DEFAULT_MAP_PROVIDER = "apple" DEFAULT_MAP_ZOOM = 18 -DEFAULT_LANGUAGE = "en" DEFAULT_EXTENDED_ATTR = False # Settings diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index b61d2999..1d2abcec 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -98,7 +98,6 @@ from .const import CONF_YAML_HASH from .const import DEFAULT_EXTENDED_ATTR from .const import DEFAULT_HOME_ZONE -from .const import DEFAULT_LANGUAGE from .const import DEFAULT_MAP_PROVIDER from .const import DEFAULT_MAP_ZOOM from .const import DEFAULT_OPTION @@ -117,7 +116,7 @@ vol.Optional(CONF_NAME): cv.string, vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.positive_int, - vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): cv.string, + vol.Optional(CONF_LANGUAGE): cv.string, # vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, } @@ -236,8 +235,8 @@ def __init__(self, hass, config, config_entry, name, unique_id): CONF_MAP_PROVIDER, DEFAULT_MAP_PROVIDER ).lower() self._map_zoom = int(config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM)) - self._language = config.setdefault(CONF_LANGUAGE, DEFAULT_LANGUAGE).lower() - self._language.replace(" ", "") + self._language = config.setdefault(CONF_LANGUAGE) + self._language = (self._language.replace(" ", "").strip() if self._language is not None else None) self._extended_attr = config.setdefault( CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR ) @@ -852,7 +851,7 @@ def do_update(self, reason): "(" + self._name + ") Map Link Type: " + str(self._map_provider) ) _LOGGER.debug( - "(" + self._name + ") Map Link generated: " + str(self._map_link) + "(" + self._name + ") Map Link URL: " + str(self._map_link) ) osm_url = ( @@ -860,8 +859,7 @@ def do_update(self, reason): + str(self._latitude) + "&lon=" + str(self._longitude) - + "&accept-language=" - + str(self._language) + + ("&accept-language=" + str(self._language) if self._language is not None else "") + "&addressdetails=1&namedetails=1&zoom=18&limit=1" + ("&email=" + str(self._api_key) if self._api_key is not None else "") ) @@ -914,10 +912,11 @@ def do_update(self, reason): place_name = osm_decoded["address"][place_category] if "name" in osm_decoded["namedetails"]: place_name = osm_decoded["namedetails"]["name"] - for language in self._language.split(","): - if "name:" + language in osm_decoded["namedetails"]: - place_name = osm_decoded["namedetails"]["name:" + language] - break + if self._language is not None: + for language in self._language.split(","): + if "name:" + language in osm_decoded["namedetails"]: + place_name = osm_decoded["namedetails"]["name:" + language] + break if not self.in_zone() and place_name != "house": new_state = place_name @@ -1243,8 +1242,7 @@ def do_update(self, reason): if self._api_key is not None else "" ) - + "&accept-language=" - + str(self._language) + + ("&accept-language=" + str(self._language) if self._language is not None else "") ) _LOGGER.info( @@ -1427,7 +1425,6 @@ def _reset_attributes(self): self._place_type = None self._place_name = None self._mtime = datetime.now() - # self._last_place_name = None self._osm_id = None self._osm_type = None self._wikidata_id = None From 9e5ff03c6b655c929c7dbebf8425e0d541692374 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 14:58:29 -0400 Subject: [PATCH 308/329] :art: Format Python code with isort & Black Code Formatter (#138) --- custom_components/places/sensor.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 1d2abcec..a6e63460 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -236,7 +236,11 @@ def __init__(self, hass, config, config_entry, name, unique_id): ).lower() self._map_zoom = int(config.setdefault(CONF_MAP_ZOOM, DEFAULT_MAP_ZOOM)) self._language = config.setdefault(CONF_LANGUAGE) - self._language = (self._language.replace(" ", "").strip() if self._language is not None else None) + self._language = ( + self._language.replace(" ", "").strip() + if self._language is not None + else None + ) self._extended_attr = config.setdefault( CONF_EXTENDED_ATTR, DEFAULT_EXTENDED_ATTR ) @@ -850,16 +854,18 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name + ") Map Link Type: " + str(self._map_provider) ) - _LOGGER.debug( - "(" + self._name + ") Map Link URL: " + str(self._map_link) - ) + _LOGGER.debug("(" + self._name + ") Map Link URL: " + str(self._map_link)) osm_url = ( "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" + str(self._latitude) + "&lon=" + str(self._longitude) - + ("&accept-language=" + str(self._language) if self._language is not None else "") + + ( + "&accept-language=" + str(self._language) + if self._language is not None + else "" + ) + "&addressdetails=1&namedetails=1&zoom=18&limit=1" + ("&email=" + str(self._api_key) if self._api_key is not None else "") ) @@ -1242,7 +1248,11 @@ def do_update(self, reason): if self._api_key is not None else "" ) - + ("&accept-language=" + str(self._language) if self._language is not None else "") + + ( + "&accept-language=" + str(self._language) + if self._language is not None + else "" + ) ) _LOGGER.info( From 4e4388cd6540f1c1be7a1c49a303d84a3edac9b7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 15:02:09 -0400 Subject: [PATCH 309/329] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 978a10bd..bb5ea5b4 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Key | Type | Required | Description | Default | `api_key` | `string` | `False` | OpenStreetMap API key (your email address). | None `map_provider` | `string` | `False` | `google`, `apple`, `osm` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` -`language` | `string` | `False` | Requested* language(s) for state and attributes. Two-Letter language code(s), separated by commas.
*Refer to Notes | location's local language +`language` | `string` | `False` | Requested\* language(s) for state and attributes. Two-Letter language code(s), separated by commas.
\*Refer to [Notes](/~https://github.com/Snuffy2/places#notes) | location's local language `extended_attr` | `boolean` | `False` | Show extended attributes: wikidata_id, osm_dict, osm_details_dict, wikidata_dict *(if they exist)*. Provides many additional attributes for advanced logic. **Warning, will make the attributes very long!** | `False` `options` | `string` | `False` | Display options: `formatted_place` *(exclusive option)*, `driving` *(can be used with formatted_place or other options)*, `zone` or `zone_name`, `place`, `place_name`, `street_number`, `street`, `city`, `county`, `state`, `postal_code`, `country`, `formatted_address`, `do_not_show_not_home` | `zone`, `place` From 8a96534ef29312bb3e9927e0f06b358d276b7c9a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 15:37:34 -0400 Subject: [PATCH 310/329] Updating Config Text --- custom_components/places/config_flow.py | 9 +++++++-- custom_components/places/strings.json | 12 ++++++------ custom_components/places/translations/en.json | 12 ++++++------ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 1e582af6..02d4361a 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -30,6 +30,7 @@ _LOGGER = logging.getLogger(__name__) MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] STATE_OPTIONS = ["zone, place", "formatted_place", "zone_name, place"] +COMPONENT_CONFIG_URL = "/~https://github.com/Snuffy2/places#configuration-options" # Note the input displayed to the user will be translated. See the # translations/.json file and strings.json. See here for further information: @@ -121,7 +122,9 @@ async def async_step_user(self, user_input=None) -> FlowResult: # If there is no user input or there were errors, show the form again, including any errors that were found with the input. return self.async_show_form( - step_id="user", data_schema=DATA_SCHEMA, errors=errors + step_id="user", data_schema=DATA_SCHEMA, errors=errors, description_placeholders={ + "component_config_url": COMPONENT_CONFIG_URL, + }, ) # this is run to import the configuration.yaml parameters\ @@ -224,5 +227,7 @@ async def async_step_init(self, user_input=None): default=self.config_entry.data[CONF_EXTENDED_ATTR], ): selector.BooleanSelector(selector.BooleanSelectorConfig()), } - ), + ), description_placeholders={ + "component_config_url": COMPONENT_CONFIG_URL, + }, ) diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index b132b2a1..9f240008 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -1,9 +1,9 @@ { - "title": "Places", + "title": "Places: OpenStreetMap Sensor", "config": { "step": { "user": { - "title": "Setup OpenStreetMap Sensor", + "title": "Places: OpenStreetMap Sensor", "data": { "name": "[%key:common::config_flow::data::name%]", "devicetracker_id": "DeviceTracker ID", @@ -15,14 +15,14 @@ "language": "Language", "extended_attr": "Extended Attributes" }, - "description": "Complete the following fields." + "description": "Create a new sensor" } } }, "options": { "step": { "init": { - "title": "Change OpenStreetMap Sensor Options", + "title": "Places: OpenStreetMap Sensor", "data": { "devicetracker_id": "DeviceTracker ID", "home_zone": "Home Zone", @@ -31,9 +31,9 @@ "map_zoom": "Map Zoom", "api_key": "[%key:common::config_flow::data::api_key%]", "language": "Language", - "extended_attr": "Extended Attributes" + "extended_attr": "Enable Extended Attributes" }, - "description": "Complete the following fields." + "description": "Update existing sensor" } } }, diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index 466ccce7..283b3b32 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -1,9 +1,9 @@ { - "title": "Places", + "title": "Places: OpenStreetMap Sensor", "config": { "step": { "user": { - "title": "Setup OpenStreetMap Sensor (places)", + "title": "Places: OpenStreetMap Sensor", "data": { "name": "Sensor Name", "devicetracker_id": "DeviceTracker ID", @@ -15,14 +15,14 @@ "language": "Language", "extended_attr": "Enable Extended Attributes" }, - "description": "Complete the following fields." + "description": "Create a new sensor\nSee [Configuration Options]({component_config_url}) on GitHub for details" } } }, "options": { "step": { "init": { - "title": "Change OpenStreetMap Sensor Options", + "title": "Places: OpenStreetMap Sensor", "data": { "devicetracker_id": "DeviceTracker ID", "home_zone": "Home Zone", @@ -31,9 +31,9 @@ "map_zoom": "Map Zoom", "api_key": "Email", "language": "Language", - "extended_attr": "Extended Attributes" + "extended_attr": "Enable Extended Attributes" }, - "description": "Complete the following fields." + "description": "Update existing sensor\nSee [Configuration Options]({component_config_url}) on GitHub for details" } } }, From 7b00e4707342de76a91e99b6bba8548a26e71124 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 15:38:19 -0400 Subject: [PATCH 311/329] :art: Format Python code with isort & Black Code Formatter (#139) --- custom_components/places/config_flow.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 02d4361a..64df2006 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -122,7 +122,10 @@ async def async_step_user(self, user_input=None) -> FlowResult: # If there is no user input or there were errors, show the form again, including any errors that were found with the input. return self.async_show_form( - step_id="user", data_schema=DATA_SCHEMA, errors=errors, description_placeholders={ + step_id="user", + data_schema=DATA_SCHEMA, + errors=errors, + description_placeholders={ "component_config_url": COMPONENT_CONFIG_URL, }, ) @@ -227,7 +230,8 @@ async def async_step_init(self, user_input=None): default=self.config_entry.data[CONF_EXTENDED_ATTR], ): selector.BooleanSelector(selector.BooleanSelectorConfig()), } - ), description_placeholders={ + ), + description_placeholders={ "component_config_url": COMPONENT_CONFIG_URL, }, ) From e360979a6ebfb44c7e2bc510d616ca248f68260e Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 15:45:15 -0400 Subject: [PATCH 312/329] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bb5ea5b4..bd670191 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,9 @@ custom_components/places/sensor.py Key | Type | Required | Description | Default | -- | -- | -- | -- | -- -`devicetracker_id` | `string` | `True` | `entity_id` of the device you wish to track | None -`name` | `string` | `True` | Friendly name of the sensor | None -`home_zone` | `string` | `False` | Used to calculate distance from home and direction of travel | `zone.home` +`devicetracker_id` | `entity_id` | `True` | The location device to track | None +`name` | `string` | `True` | Friendly name of the places sensor | None +`home_zone` | `entity_id` | `False` | Used to calculate distance from home and direction of travel | `zone.home` `api_key` | `string` | `False` | OpenStreetMap API key (your email address). | None `map_provider` | `string` | `False` | `google`, `apple`, `osm` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` From 4f25dcde18a561e93ae1f3d75f4c251acf0875e7 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 16:20:19 -0400 Subject: [PATCH 313/329] Config Strings Updates --- custom_components/places/config_flow.py | 8 +++++--- custom_components/places/strings.json | 8 ++++---- custom_components/places/translations/en.json | 10 +++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 64df2006..45f249f1 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -30,6 +30,8 @@ _LOGGER = logging.getLogger(__name__) MAP_PROVIDER_OPTIONS = ["apple", "google", "osm"] STATE_OPTIONS = ["zone, place", "formatted_place", "zone_name, place"] +MAP_ZOOM_MIN = 1 +MAP_ZOOM_MAX = 20 COMPONENT_CONFIG_URL = "/~https://github.com/Snuffy2/places#configuration-options" # Note the input displayed to the user will be translated. See the @@ -70,7 +72,7 @@ CONF_MAP_ZOOM, default=int(DEFAULT_MAP_ZOOM) ): selector.NumberSelector( selector.NumberSelectorConfig( - min=1, max=20, mode=selector.NumberSelectorMode.BOX + min=MAP_ZOOM_MIN, max=MAP_ZOOM_MAX, mode=selector.NumberSelectorMode.BOX ) ), vol.Optional(CONF_LANGUAGE): str, @@ -173,7 +175,6 @@ async def async_step_init(self, user_input=None): self.config_entry, data=user_input, options=self.config_entry.options ) return self.async_create_entry(title="", data={}) - # return self.async_create_entry(title=DOMAIN, data=user_input) return self.async_show_form( step_id="init", @@ -219,7 +220,7 @@ async def async_step_init(self, user_input=None): CONF_MAP_ZOOM, default=self.config_entry.data[CONF_MAP_ZOOM] ): selector.NumberSelector( selector.NumberSelectorConfig( - min=1, max=20, mode=selector.NumberSelectorMode.BOX + min=MAP_ZOOM_MIN, max=MAP_ZOOM_MAX, mode=selector.NumberSelectorMode.BOX ) ), vol.Optional( @@ -233,5 +234,6 @@ async def async_step_init(self, user_input=None): ), description_placeholders={ "component_config_url": COMPONENT_CONFIG_URL, + "sensor_name": self.config_entry.data[CONF_NAME], }, ) diff --git a/custom_components/places/strings.json b/custom_components/places/strings.json index 9f240008..56676e58 100644 --- a/custom_components/places/strings.json +++ b/custom_components/places/strings.json @@ -11,8 +11,8 @@ "options": "Display Options", "map_provider": "Map Provider", "map_zoom": "Map Zoom", - "api_key": "[%key:common::config_flow::data::api_key%]", - "language": "Language", + "api_key": "Email to use as OpenStreetMap API Key (optional)", + "language": "Language (optional)", "extended_attr": "Extended Attributes" }, "description": "Create a new sensor" @@ -29,8 +29,8 @@ "options": "Display Options", "map_provider": "Map Provider", "map_zoom": "Map Zoom", - "api_key": "[%key:common::config_flow::data::api_key%]", - "language": "Language", + "api_key": "Email to use as OpenStreetMap API Key (optional)", + "language": "Language (optional)", "extended_attr": "Enable Extended Attributes" }, "description": "Update existing sensor" diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index 283b3b32..5d7eaa77 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -11,8 +11,8 @@ "options": "Display Options", "map_provider": "Map Provider", "map_zoom": "Map Zoom", - "api_key": "Email", - "language": "Language", + "api_key": "Email to use as OpenStreetMap API Key (optional)", + "language": "Language (optional)", "extended_attr": "Enable Extended Attributes" }, "description": "Create a new sensor\nSee [Configuration Options]({component_config_url}) on GitHub for details" @@ -29,11 +29,11 @@ "options": "Display Options", "map_provider": "Map Provider", "map_zoom": "Map Zoom", - "api_key": "Email", - "language": "Language", + "api_key": "Email to use as OpenStreetMap API Key (optional)", + "language": "Language (optional)", "extended_attr": "Enable Extended Attributes" }, - "description": "Update existing sensor\nSee [Configuration Options]({component_config_url}) on GitHub for details" + "description": "**Updating sensor:{sensor_name}**\nSee [Configuration Options]({component_config_url}) on GitHub for details" } } }, From 01ff25faff2229e4a4bf30d1f3aaa8fa12b7f0e4 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 16:20:59 -0400 Subject: [PATCH 314/329] :art: Format Python code with isort & Black Code Formatter (#140) --- custom_components/places/config_flow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 45f249f1..f9d8bd00 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -220,7 +220,9 @@ async def async_step_init(self, user_input=None): CONF_MAP_ZOOM, default=self.config_entry.data[CONF_MAP_ZOOM] ): selector.NumberSelector( selector.NumberSelectorConfig( - min=MAP_ZOOM_MIN, max=MAP_ZOOM_MAX, mode=selector.NumberSelectorMode.BOX + min=MAP_ZOOM_MIN, + max=MAP_ZOOM_MAX, + mode=selector.NumberSelectorMode.BOX, ) ), vol.Optional( From 316690f300249309078e31cd33622c9657a082d3 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 16:24:22 -0400 Subject: [PATCH 315/329] Update en.json --- custom_components/places/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index 5d7eaa77..a67c885b 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -33,7 +33,7 @@ "language": "Language (optional)", "extended_attr": "Enable Extended Attributes" }, - "description": "**Updating sensor:{sensor_name}**\nSee [Configuration Options]({component_config_url}) on GitHub for details" + "description": "**Updating sensor: {sensor_name}**\nSee [Configuration Options]({component_config_url}) on GitHub for details" } } }, From 98083e29b6a4dc783fde8a0def63eca7c2317503 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 22:47:58 -0400 Subject: [PATCH 316/329] Further fixes --- custom_components/places/config_flow.py | 18 +++++++------- custom_components/places/sensor.py | 24 ++++++++++++------- custom_components/places/translations/en.json | 2 +- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index f9d8bd00..5d1478c9 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -180,18 +180,18 @@ async def async_step_init(self, user_input=None): step_id="init", data_schema=vol.Schema( { - # vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME]): str, + # vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME] if CONF_NAME in self.config_entry.data else None)): str, vol.Required( CONF_DEVICETRACKER_ID, - default=self.config_entry.data[CONF_DEVICETRACKER_ID], + default=(self.config_entry.data[CONF_DEVICETRACKER_ID] if CONF_DEVICETRACKER_ID in self.config_entry.data else None) ): selector.EntitySelector( selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) ), vol.Optional( - CONF_API_KEY, default=self.config_entry.data[CONF_API_KEY] + CONF_API_KEY, default=(self.config_entry.data[CONF_API_KEY] if CONF_API_KEY in self.config_entry.data else None) ): str, vol.Optional( - CONF_OPTIONS, default=self.config_entry.data[CONF_OPTIONS] + CONF_OPTIONS, default=(self.config_entry.data[CONF_OPTIONS] if CONF_OPTIONS in self.config_entry.data else None) ): selector.SelectSelector( selector.SelectSelectorConfig( options=STATE_OPTIONS, @@ -201,13 +201,13 @@ async def async_step_init(self, user_input=None): ) ), vol.Optional( - CONF_HOME_ZONE, default=self.config_entry.data[CONF_HOME_ZONE] + CONF_HOME_ZONE, default=(self.config_entry.data[CONF_HOME_ZONE] if CONF_HOME_ZONE in self.config_entry.data else None) ): selector.EntitySelector( selector.SingleEntitySelectorConfig(domain=HOME_LOCATION_DOMAIN) ), vol.Optional( CONF_MAP_PROVIDER, - default=self.config_entry.data[CONF_MAP_PROVIDER], + default=(self.config_entry.data[CONF_MAP_PROVIDER] if CONF_MAP_PROVIDER in self.config_entry.data else None) ): selector.SelectSelector( selector.SelectSelectorConfig( options=MAP_PROVIDER_OPTIONS, @@ -217,7 +217,7 @@ async def async_step_init(self, user_input=None): ) ), vol.Optional( - CONF_MAP_ZOOM, default=self.config_entry.data[CONF_MAP_ZOOM] + CONF_MAP_ZOOM, default=(self.config_entry.data[CONF_MAP_ZOOM] if CONF_MAP_ZOOM in self.config_entry.data else None) ): selector.NumberSelector( selector.NumberSelectorConfig( min=MAP_ZOOM_MIN, @@ -226,11 +226,11 @@ async def async_step_init(self, user_input=None): ) ), vol.Optional( - CONF_LANGUAGE, default=self.config_entry.data[CONF_LANGUAGE] + CONF_LANGUAGE, default=(self.config_entry.data[CONF_LANGUAGE] if CONF_LANGUAGE in self.config_entry.data else None) ): str, vol.Optional( CONF_EXTENDED_ATTR, - default=self.config_entry.data[CONF_EXTENDED_ATTR], + default=(self.config_entry.data[CONF_EXTENDED_ATTR] if CONF_EXTENDED_ATTR in self.config_entry.data else None) ): selector.BooleanSelector(selector.BooleanSelectorConfig()), } ), diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index a6e63460..7a5f87db 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -38,7 +38,7 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_call_later -from homeassistant.helpers.event import async_track_state_change +from homeassistant.helpers.event import async_track_state_change, async_track_state_change_event from homeassistant.helpers.issue_registry import IssueSeverity from homeassistant.helpers.issue_registry import async_create_issue from homeassistant.helpers.typing import ConfigType @@ -180,9 +180,10 @@ def do_import(_): # _LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) all_yaml_hashes = [] - for m in list(hass.data[DOMAIN].values()): - if CONF_YAML_HASH in m: - all_yaml_hashes.append(m[CONF_YAML_HASH]) + if DOMAIN in hass.data and hass.data[DOMAIN] is not None and hass.data[DOMAIN].values() is not None: + for m in list(hass.data[DOMAIN].values()): + if CONF_YAML_HASH in m: + all_yaml_hashes.append(m[CONF_YAML_HASH]) # _LOGGER.debug("[async_setup_platform] New yaml hash: " + str(data.get(CONF_YAML_HASH))) # _LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) @@ -306,12 +307,17 @@ def __init__(self, hass, config, config_entry, name, unique_id): + self._devicetracker_id ) - async_track_state_change( + #async_track_state_change( + # hass, + # self._devicetracker_id, + # self.tsc_update, + # from_state=None, + # to_state=None, + #) + async_track_state_change_event( hass, self._devicetracker_id, self.tsc_update, - from_state=None, - to_state=None, ) _LOGGER.info( "(" @@ -449,8 +455,8 @@ def is_devicetracker_set(self): return True else: return False - - def tsc_update(self, tscarg2, tsarg3, tsarg4): + #def tsc_update(self, tscarg2, tsarg3, tsarg4): + def tsc_update(self, tscarg=None): """Call the do_update function based on the TSC (track state change) event""" if self.is_devicetracker_set(): # _LOGGER.debug( diff --git a/custom_components/places/translations/en.json b/custom_components/places/translations/en.json index a67c885b..a5318e87 100644 --- a/custom_components/places/translations/en.json +++ b/custom_components/places/translations/en.json @@ -33,7 +33,7 @@ "language": "Language (optional)", "extended_attr": "Enable Extended Attributes" }, - "description": "**Updating sensor: {sensor_name}**\nSee [Configuration Options]({component_config_url}) on GitHub for details" + "description": "**Updating sensor: {sensor_name}**\nSee [Configuration Options]({component_config_url}) on GitHub for details" } } }, From 38a2253c2a3d4ecc03bf663d74caf6e0e05dd49a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 22:48:41 -0400 Subject: [PATCH 317/329] :art: Format Python code with isort & Black Code Formatter (#141) --- custom_components/places/config_flow.py | 53 +++++++++++++++++++++---- custom_components/places/sensor.py | 16 +++++--- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index 5d1478c9..cada597d 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -183,15 +183,29 @@ async def async_step_init(self, user_input=None): # vol.Required(CONF_NAME, default=self.config_entry.data[CONF_NAME] if CONF_NAME in self.config_entry.data else None)): str, vol.Required( CONF_DEVICETRACKER_ID, - default=(self.config_entry.data[CONF_DEVICETRACKER_ID] if CONF_DEVICETRACKER_ID in self.config_entry.data else None) + default=( + self.config_entry.data[CONF_DEVICETRACKER_ID] + if CONF_DEVICETRACKER_ID in self.config_entry.data + else None + ), ): selector.EntitySelector( selector.SingleEntitySelectorConfig(domain=TRACKING_DOMAIN) ), vol.Optional( - CONF_API_KEY, default=(self.config_entry.data[CONF_API_KEY] if CONF_API_KEY in self.config_entry.data else None) + CONF_API_KEY, + default=( + self.config_entry.data[CONF_API_KEY] + if CONF_API_KEY in self.config_entry.data + else None + ), ): str, vol.Optional( - CONF_OPTIONS, default=(self.config_entry.data[CONF_OPTIONS] if CONF_OPTIONS in self.config_entry.data else None) + CONF_OPTIONS, + default=( + self.config_entry.data[CONF_OPTIONS] + if CONF_OPTIONS in self.config_entry.data + else None + ), ): selector.SelectSelector( selector.SelectSelectorConfig( options=STATE_OPTIONS, @@ -201,13 +215,22 @@ async def async_step_init(self, user_input=None): ) ), vol.Optional( - CONF_HOME_ZONE, default=(self.config_entry.data[CONF_HOME_ZONE] if CONF_HOME_ZONE in self.config_entry.data else None) + CONF_HOME_ZONE, + default=( + self.config_entry.data[CONF_HOME_ZONE] + if CONF_HOME_ZONE in self.config_entry.data + else None + ), ): selector.EntitySelector( selector.SingleEntitySelectorConfig(domain=HOME_LOCATION_DOMAIN) ), vol.Optional( CONF_MAP_PROVIDER, - default=(self.config_entry.data[CONF_MAP_PROVIDER] if CONF_MAP_PROVIDER in self.config_entry.data else None) + default=( + self.config_entry.data[CONF_MAP_PROVIDER] + if CONF_MAP_PROVIDER in self.config_entry.data + else None + ), ): selector.SelectSelector( selector.SelectSelectorConfig( options=MAP_PROVIDER_OPTIONS, @@ -217,7 +240,12 @@ async def async_step_init(self, user_input=None): ) ), vol.Optional( - CONF_MAP_ZOOM, default=(self.config_entry.data[CONF_MAP_ZOOM] if CONF_MAP_ZOOM in self.config_entry.data else None) + CONF_MAP_ZOOM, + default=( + self.config_entry.data[CONF_MAP_ZOOM] + if CONF_MAP_ZOOM in self.config_entry.data + else None + ), ): selector.NumberSelector( selector.NumberSelectorConfig( min=MAP_ZOOM_MIN, @@ -226,11 +254,20 @@ async def async_step_init(self, user_input=None): ) ), vol.Optional( - CONF_LANGUAGE, default=(self.config_entry.data[CONF_LANGUAGE] if CONF_LANGUAGE in self.config_entry.data else None) + CONF_LANGUAGE, + default=( + self.config_entry.data[CONF_LANGUAGE] + if CONF_LANGUAGE in self.config_entry.data + else None + ), ): str, vol.Optional( CONF_EXTENDED_ATTR, - default=(self.config_entry.data[CONF_EXTENDED_ATTR] if CONF_EXTENDED_ATTR in self.config_entry.data else None) + default=( + self.config_entry.data[CONF_EXTENDED_ATTR] + if CONF_EXTENDED_ATTR in self.config_entry.data + else None + ), ): selector.BooleanSelector(selector.BooleanSelectorConfig()), } ), diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 7a5f87db..2ac701c0 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -38,7 +38,8 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_call_later -from homeassistant.helpers.event import async_track_state_change, async_track_state_change_event +from homeassistant.helpers.event import async_track_state_change +from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.issue_registry import IssueSeverity from homeassistant.helpers.issue_registry import async_create_issue from homeassistant.helpers.typing import ConfigType @@ -180,7 +181,11 @@ def do_import(_): # _LOGGER.debug("[async_setup_platform] final import_config: " + str(import_config)) all_yaml_hashes = [] - if DOMAIN in hass.data and hass.data[DOMAIN] is not None and hass.data[DOMAIN].values() is not None: + if ( + DOMAIN in hass.data + and hass.data[DOMAIN] is not None + and hass.data[DOMAIN].values() is not None + ): for m in list(hass.data[DOMAIN].values()): if CONF_YAML_HASH in m: all_yaml_hashes.append(m[CONF_YAML_HASH]) @@ -307,13 +312,13 @@ def __init__(self, hass, config, config_entry, name, unique_id): + self._devicetracker_id ) - #async_track_state_change( + # async_track_state_change( # hass, # self._devicetracker_id, # self.tsc_update, # from_state=None, # to_state=None, - #) + # ) async_track_state_change_event( hass, self._devicetracker_id, @@ -455,7 +460,8 @@ def is_devicetracker_set(self): return True else: return False - #def tsc_update(self, tscarg2, tsarg3, tsarg4): + + # def tsc_update(self, tscarg2, tsarg3, tsarg4): def tsc_update(self, tscarg=None): """Call the do_update function based on the TSC (track state change) event""" if self.is_devicetracker_set(): From 63f3f9a7b7b041c4fc3b295941967548fface21a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 22:50:36 -0400 Subject: [PATCH 318/329] flake8 Fixes --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 2ac701c0..e45b00f2 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -38,7 +38,7 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_call_later -from homeassistant.helpers.event import async_track_state_change +#from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.issue_registry import IssueSeverity from homeassistant.helpers.issue_registry import async_create_issue From ae01cf61bb05a1f237f9357b03ca0330a030c025 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sat, 17 Sep 2022 22:51:43 -0400 Subject: [PATCH 319/329] :art: Format Python code with isort & Black Code Formatter (#142) --- custom_components/places/sensor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index e45b00f2..d47d905d 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -37,8 +37,9 @@ from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback + +# from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.event import async_call_later -#from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.issue_registry import IssueSeverity from homeassistant.helpers.issue_registry import async_create_issue From d29bf6910dd12f78dfa7ef17be5810f071e6d2df Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 18 Sep 2022 22:14:23 -0400 Subject: [PATCH 320/329] Revert temporary naming for testing --- custom_components/places/const.py | 2 +- custom_components/places/manifest.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/places/const.py b/custom_components/places/const.py index 36533106..0047e43a 100644 --- a/custom_components/places/const.py +++ b/custom_components/places/const.py @@ -1,7 +1,7 @@ from homeassistant.const import CONF_ZONE from homeassistant.const import Platform -DOMAIN = "placesv2dev" +DOMAIN = "places" # Defaults DEFAULT_ICON = "mdi:map-marker-circle" diff --git a/custom_components/places/manifest.json b/custom_components/places/manifest.json index 32831dda..df434590 100644 --- a/custom_components/places/manifest.json +++ b/custom_components/places/manifest.json @@ -1,6 +1,6 @@ { - "domain": "placesv2dev", - "name": "Places v2-dev", + "domain": "places", + "name": "Places", "version":"2", "config_flow": true, "documentation": "/~https://github.com/Snuffy2/places", From 3a2228858d566779ab8ee3f8767c82c0ce480aaf Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 18 Sep 2022 22:41:02 -0400 Subject: [PATCH 321/329] Minor Logger Changes --- custom_components/places/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index d47d905d..7cd00499 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -194,14 +194,14 @@ def do_import(_): # _LOGGER.debug("[async_setup_platform] New yaml hash: " + str(data.get(CONF_YAML_HASH))) # _LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) if import_config[CONF_YAML_HASH] not in all_yaml_hashes: - _LOGGER.debug( - "[async_setup_platform] New YAML sensor, importing: " + _LOGGER.warning( + "New YAML sensor, importing: " + str(import_config.get(CONF_NAME)) ) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) else: - _LOGGER.debug( - "[async_setup_platform] YAML sensor already imported, ignoring: " + _LOGGER.info( + "YAML sensor already imported, ignoring: " + str(import_config.get(CONF_NAME)) ) From 2b6ceddd4e053085687c6678e95a2c5b4e3ff685 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 18 Sep 2022 22:42:07 -0400 Subject: [PATCH 322/329] :art: Format Python code with isort & Black Code Formatter (#144) --- custom_components/places/sensor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 7cd00499..9d4685c8 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -195,8 +195,7 @@ def do_import(_): # _LOGGER.debug("[async_setup_platform] All yaml hashes: " + str(all_yaml_hashes)) if import_config[CONF_YAML_HASH] not in all_yaml_hashes: _LOGGER.warning( - "New YAML sensor, importing: " - + str(import_config.get(CONF_NAME)) + "New YAML sensor, importing: " + str(import_config.get(CONF_NAME)) ) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_import) else: From 2e861e61ca3862c36d06d58ee80244180d23c069 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 18 Sep 2022 23:28:23 -0400 Subject: [PATCH 323/329] Tweaking logging and levels --- custom_components/places/sensor.py | 49 ++++++++++++++---------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 9d4685c8..34afe59e 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -7,7 +7,7 @@ Description: Provides a sensor with a variable state consisting of reverse geocode (place) details for a linked device_tracker entity that provides GPS co-ordinates (ie owntracks, icloud) - Optionally allows you to specify a 'home_zone' for each device and calculates distance from home and direction of travel. + Allows you to specify a 'home_zone' for each device and calculates distance from home and direction of travel. Configuration Instructions are on GitHub. GitHub: /~https://github.com/Snuffy2/places @@ -38,7 +38,6 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback -# from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.issue_registry import IssueSeverity @@ -119,7 +118,6 @@ vol.Optional(CONF_MAP_PROVIDER, default=DEFAULT_MAP_PROVIDER): cv.string, vol.Optional(CONF_MAP_ZOOM, default=DEFAULT_MAP_ZOOM): cv.positive_int, vol.Optional(CONF_LANGUAGE): cv.string, - # vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, vol.Optional(CONF_EXTENDED_ATTR, default=DEFAULT_EXTENDED_ATTR): cv.boolean, } ) @@ -220,13 +218,12 @@ async def async_setup_entry( [Places(hass, config, config_entry, name, unique_id)], update_before_add=True ) - class Places(Entity): """Representation of a Places Sensor.""" def __init__(self, hass, config, config_entry, name, unique_id): """Initialize the sensor.""" - _LOGGER.debug("(" + str(name) + ") [Init] Places sensor: " + str(name)) + _LOGGER.info("(" + str(name) + ") [Init] Places sensor: " + str(name)) self._config = config self._config_entry = config_entry @@ -461,7 +458,6 @@ def is_devicetracker_set(self): else: return False - # def tsc_update(self, tscarg2, tsarg3, tsarg4): def tsc_update(self, tscarg=None): """Call the do_update function based on the TSC (track state change) event""" if self.is_devicetracker_set(): @@ -488,7 +484,6 @@ async def async_update(self): # + ") [Async Update] Running Update - Devicetracker is set" # ) await self._hass.async_add_executor_job(self.do_update, "Scan Interval") - # self.do_update("Scan Interval") # else: # _LOGGER.debug( # "(" @@ -740,7 +735,7 @@ def do_update(self, reason): """Update if location has changed.""" devicetracker_zone = self._hass.states.get(self._devicetracker_id).state - _LOGGER.info( + _LOGGER.debug( "(" + self._name + ") DeviceTracker Zone: " + str(devicetracker_zone) ) @@ -789,10 +784,6 @@ def do_update(self, reason): + ", home_longitude=" + str(home_longitude) ) - # else: - # _LOGGER.error( - # "(" + self._name + ") Missing _devicetracker_id, this will likely error" - # ) proceed_with_update = True initial_update = False @@ -828,7 +819,7 @@ def do_update(self, reason): initial_update = True if proceed_with_update and devicetracker_zone: - _LOGGER.debug( + _LOGGER.info( "(" + self._name + ") Meets criteria, proceeding with OpenStreetMap query" @@ -837,7 +828,7 @@ def do_update(self, reason): _LOGGER.info( "(" + self._name - + ") DeviceTracker Zone (current): " + + ") DeviceTracker Zone: " + str(self._devicetracker_zone) + " / Skipped Updates: " + str(self._updateskipped) @@ -1031,8 +1022,8 @@ def do_update(self, reason): else: _LOGGER.debug("(" + self._name + ") Keeping initial last_place_name") self._last_place_name = last_place_name - _LOGGER.debug( - "(" + self._name + ") Last Place Name (Final): " + str(last_place_name) + _LOGGER.info( + "(" + self._name + ") Last Place Name: " + str(last_place_name) ) isDriving = False @@ -1114,7 +1105,7 @@ def do_update(self, reason): ) elif "formatted_place" in display_options: new_state = self._formatted_place - _LOGGER.info( + _LOGGER.debug( "(" + self._name + ") New State using formatted_place: " @@ -1122,7 +1113,7 @@ def do_update(self, reason): ) elif not self.in_zone(): - # Options: "formatted_place, zone, zone_name, place, street_number, street, city, county, state, postal_code, country, formatted_address" + # Options: "formatted_place, driving, zone, zone_name, place_name, place, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home" _LOGGER.debug( "(" @@ -1141,14 +1132,12 @@ def do_update(self, reason): and "do_not_show_not_home" not in display_options and self._devicetracker_zone_name is not None ): - # zone = self._devicetracker_zone user_display.append(self._devicetracker_zone_name) elif ( "zone" in display_options and "do_not_show_not_home" not in display_options and self._devicetracker_zone is not None ): - # zone = self._devicetracker_zone user_display.append(self._devicetracker_zone) if "place_name" in display_options and place_name is not None: @@ -1355,10 +1344,10 @@ def do_update(self, reason): # ) self._wikidata_dict = wikidata_dict if new_state is not None: - _LOGGER.debug( - "(" + self._name + ") New State (Final): " + str(new_state) - ) self._state = new_state[:255] + _LOGGER.info( + "(" + self._name + ") New State: " + str(self._state) + ) else: self._state = "" _LOGGER.warning( @@ -1367,7 +1356,7 @@ def do_update(self, reason): + ") New State is None, setting to: " + str(self._state) ) - _LOGGER.debug("(" + self._name + ") Building EventData") + _LOGGER.debug("(" + self._name + ") Building Event Data") event_data = {} event_data["entity"] = self._name event_data["from_state"] = previous_state @@ -1419,13 +1408,21 @@ def do_update(self, reason): _LOGGER.debug( "(" + self._name - + ") Event Fired [event_type: " + + ") Event Details [event_type: " + DOMAIN + "_state_update]: " + str(event_data) ) + _LOGGER.info( + "(" + + self._name + + ") Event Fired [event_type: " + + DOMAIN + + "_state_update]" + ) + else: - _LOGGER.debug( + _LOGGER.info( "(" + self._name + ") No entity update needed, Previous State = New State" From b8177d0c5d617d4231bb427dd5356fbfeeb944b8 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 18 Sep 2022 23:29:39 -0400 Subject: [PATCH 324/329] :art: Format Python code with isort & Black Code Formatter (#145) --- custom_components/places/sensor.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 34afe59e..8354d832 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -37,7 +37,6 @@ from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback - from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.issue_registry import IssueSeverity @@ -218,6 +217,7 @@ async def async_setup_entry( [Places(hass, config, config_entry, name, unique_id)], update_before_add=True ) + class Places(Entity): """Representation of a Places Sensor.""" @@ -1345,9 +1345,7 @@ def do_update(self, reason): self._wikidata_dict = wikidata_dict if new_state is not None: self._state = new_state[:255] - _LOGGER.info( - "(" + self._name + ") New State: " + str(self._state) - ) + _LOGGER.info("(" + self._name + ") New State: " + str(self._state)) else: self._state = "" _LOGGER.warning( From 66d98b8770d1291f03dbf4ac7d771322b22b365c Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Sun, 18 Sep 2022 23:47:31 -0400 Subject: [PATCH 325/329] Logging Tweaks --- custom_components/places/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 8354d832..c85b947f 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -789,20 +789,20 @@ def do_update(self, reason): initial_update = False if current_location == previous_location: - _LOGGER.debug( + _LOGGER.info( "(" + self._name + ") Stopping update because coordinates are identical" ) proceed_with_update = False elif int(distance_traveled) > 0 and self._updateskipped > 3: proceed_with_update = True - _LOGGER.debug( + _LOGGER.info( "(" + self._name + ") Allowing update after 3 skips even with distance traveled < 10m" ) elif int(distance_traveled) < 10: self._updateskipped = self._updateskipped + 1 - _LOGGER.debug( + _LOGGER.info( "(" + self._name + ") Stopping update because location changed " @@ -814,7 +814,7 @@ def do_update(self, reason): proceed_with_update = False if previous_state == "Initializing...": - _LOGGER.debug("(" + self._name + ") Performing Initial Update for user...") + _LOGGER.info("(" + self._name + ") Performing Initial Update for user...") proceed_with_update = True initial_update = True From 5bea19b93de4dd548fb92c38ebac3ff9ad4a1814 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 19 Sep 2022 00:07:05 -0400 Subject: [PATCH 326/329] Update sensor.py --- custom_components/places/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index c85b947f..161a1a26 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -321,7 +321,7 @@ def __init__(self, hass, config, config_entry, name, unique_id): self._devicetracker_id, self.tsc_update, ) - _LOGGER.info( + _LOGGER.debug( "(" + self._name + ") [Init] Subscribed to DeviceTracker state change events" From 5e970f19b50ea5fdcdca58a2bbf94c6104dd73a6 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 19 Sep 2022 18:31:58 -0400 Subject: [PATCH 327/329] Preparing for PR back to primary --- README.md | 20 ++++++++++---------- custom_components/places/config_flow.py | 2 +- custom_components/places/manifest.json | 6 +++--- custom_components/places/sensor.py | 5 ++--- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index bd670191..e35fe69a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Key | Type | Required | Description | Default | `api_key` | `string` | `False` | OpenStreetMap API key (your email address). | None `map_provider` | `string` | `False` | `google`, `apple`, `osm` | `apple` `map_zoom` | `number` | `False` | Level of zoom for the generated map link <1-20> | `18` -`language` | `string` | `False` | Requested\* language(s) for state and attributes. Two-Letter language code(s), separated by commas.
\*Refer to [Notes](/~https://github.com/Snuffy2/places#notes) | location's local language +`language` | `string` | `False` | Requested\* language(s) for state and attributes. Two-Letter language code(s), separated by commas.
\*Refer to [Notes](#notes) | location's local language `extended_attr` | `boolean` | `False` | Show extended attributes: wikidata_id, osm_dict, osm_details_dict, wikidata_dict *(if they exist)*. Provides many additional attributes for advanced logic. **Warning, will make the attributes very long!** | `False` `options` | `string` | `False` | Display options: `formatted_place` *(exclusive option)*, `driving` *(can be used with formatted_place or other options)*, `zone` or `zone_name`, `place`, `place_name`, `street_number`, `street`, `city`, `county`, `state`, `postal_code`, `country`, `formatted_address`, `do_not_show_not_home` | `zone`, `place` @@ -160,7 +160,7 @@ Sample generic automations.yaml snippet to send an iOS notify on any device stat ## Prior Contributions: * Original Author: [Jim Thompson](/~https://github.com/tenly2000) -* Subsequent Author: [Ian Richardson](/~https://github.com/iantrich) +* Subsequent Authors: [Ian Richardson](/~https://github.com/iantrich) & [Snuffy2](/~https://github.com/Snuffy2) ## Contributions are welcome! @@ -168,16 +168,16 @@ If you want to contribute to this please read the [Contribution guidelines](CONT *** -[places]: /~https://github.com/Snuffy2/places -[commits-shield]: https://img.shields.io/github/commit-activity/y/Snuffy2/places?style=for-the-badge -[commits]: /~https://github.com/Snuffy2/places/commits/newdev -[hacs]: /~https://github.com/hacs/integration +[places]: /~https://github.com/custom-components/places +[commits-shield]: https://img.shields.io/github/commit-activity/y/custom-components/places.svg?style=for-the-badge +[commits]: /~https://github.com/custom-components/places/commits/master +[hacs]: /~https://github.com/custom-components/hacs [hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge [discord]: https://discord.gg/Qa5fW2R [discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge [forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge [forum]: https://community.home-assistant.io/t/reverse-geocode-sensor-places-using-openstreetmap-custom-component -[license-shield]: https://img.shields.io/github/license/Snuffy2/places.svg?style=for-the-badge -[releases-shield]: https://img.shields.io/github/v/release/Snuffy2/places?style=for-the-badge -[releases]: /~https://github.com/Snuffy2/places/releases - +[license-shield]: https://img.shields.io/github/license/custom-components/places.svg?style=for-the-badge +[maintenance-shield]: https://img.shields.io/badge/maintainer-Ian%20Richardson%20%40iantrich-blue.svg?style=for-the-badge +[releases-shield]: https://img.shields.io/github/release/custom-components/places.svg?style=for-the-badge +[releases]: /~https://github.com/custom-components/places/releases diff --git a/custom_components/places/config_flow.py b/custom_components/places/config_flow.py index cada597d..21d9548a 100644 --- a/custom_components/places/config_flow.py +++ b/custom_components/places/config_flow.py @@ -32,7 +32,7 @@ STATE_OPTIONS = ["zone, place", "formatted_place", "zone_name, place"] MAP_ZOOM_MIN = 1 MAP_ZOOM_MAX = 20 -COMPONENT_CONFIG_URL = "/~https://github.com/Snuffy2/places#configuration-options" +COMPONENT_CONFIG_URL = "/~https://github.com/custom-components/places#configuration-options" # Note the input displayed to the user will be translated. See the # translations/.json file and strings.json. See here for further information: diff --git a/custom_components/places/manifest.json b/custom_components/places/manifest.json index df434590..6b9f30d3 100644 --- a/custom_components/places/manifest.json +++ b/custom_components/places/manifest.json @@ -3,10 +3,10 @@ "name": "Places", "version":"2", "config_flow": true, - "documentation": "/~https://github.com/Snuffy2/places", - "issue_tracker": "/~https://github.com/Snuffy2/places/issues", + "documentation": "/~https://github.com/custom-components/places", + "issue_tracker": "/~https://github.com/custom-components/places/issues", "dependencies": ["device_tracker"], - "codeowners": ["@Snuffy2"], + "codeowners": ["@tenly2000","@iantrich","@Snuffy2"], "requirements": [], "iot_class": "cloud_polling" } diff --git a/custom_components/places/sensor.py b/custom_components/places/sensor.py index 161a1a26..dd032b15 100644 --- a/custom_components/places/sensor.py +++ b/custom_components/places/sensor.py @@ -2,15 +2,14 @@ Place Support for OpenStreetMap Geocode sensors. Original Author: Jim Thompson -Subsequent Author: Ian Richardson -Current Author: Snuffy2 +Subsequent Authors: Ian Richardson & Snuffy2 Description: Provides a sensor with a variable state consisting of reverse geocode (place) details for a linked device_tracker entity that provides GPS co-ordinates (ie owntracks, icloud) Allows you to specify a 'home_zone' for each device and calculates distance from home and direction of travel. Configuration Instructions are on GitHub. -GitHub: /~https://github.com/Snuffy2/places +GitHub: /~https://github.com/custom-components/places """ import hashlib From 346a3668f4f9f660db6fe71003c03caa8842380a Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 19 Sep 2022 18:36:09 -0400 Subject: [PATCH 328/329] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e35fe69a..1e1ce361 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Unless you have a good reason not to, you probably want to install this componen 1. Ensure that [HACS](https://hacs.xyz/) is installed 1. Navigate to HACS -> Integrations 1. Open the three-dot menu and select 'Custom Repositories' -1. Put '/~https://github.com/Snuffy2/places' into the 'Repository' textbox. +1. Put '(/../../)' into the 'Repository' textbox. 1. Select 'Integration' as the category 1. Press 'Add'. 1. Find the Places integration in the HACS integration list and install it From f512b022d76ff0838fb9dff27e982b6026c6f2a0 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 19 Sep 2022 18:38:22 -0400 Subject: [PATCH 329/329] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e1ce361..96670f42 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Unless you have a good reason not to, you probably want to install this componen 1. Ensure that [HACS](https://hacs.xyz/) is installed 1. Navigate to HACS -> Integrations 1. Open the three-dot menu and select 'Custom Repositories' -1. Put '(/../../)' into the 'Repository' textbox. +1. Put '/~https://github.com/custom-components/places' into the 'Repository' textbox. 1. Select 'Integration' as the category 1. Press 'Add'. 1. Find the Places integration in the HACS integration list and install it