Skip to content

Commit

Permalink
iCloud3 v3.0.rc8
Browse files Browse the repository at this point in the history
iCloud3 Release Candidate 8
  • Loading branch information
gcobb321 committed Oct 25, 2023
1 parent 7e8b2a4 commit c42a05a
Show file tree
Hide file tree
Showing 15 changed files with 331 additions and 222 deletions.
18 changes: 14 additions & 4 deletions custom_components/icloud3/ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
rc7.1 - Release Candidate 7.1 (10/15/2023)
rc8 - 10/25/2023
...............................
1. Configure Settings - Made the following changes:
1. Minor text changes to field names and screens.
2. Improved the error messages when experiencing a problem logging into the iCloud Account.
3. Fixed a bug when selecting the Enter Verification Code screen before logging into the iCloud account.
2. Old Location Error Notifications - Fixed a problem where Old Location notifications were constantly being sent to a phone when the maximum number of old location errors (20) had been encountered.
3. iOSApp Location Time - If the location time is older than 3-hours, it's age is displayed (4.5 hrs ago) instead of the time (6:15:00p).

rc7.1/rc7.1.1 - 10/15/2023
...............................
1. Zone-Device Count bug fix - Fixed a bug where the device counts were not being displayed correctly.
2. Exit Zone for Devices without the iOSApp (Watch) - When a Device exits a zone, all other devices that were in the same zone that do not have the iOS App installed will be updated immediately. They were being updated when their next update timer was reached. Hopefully, this will make Watch zone exit updates to be done when they happen.
3. Apple account password - When iCloud3 starts, the password is checked to see if it is encoded in the configuration parameter file. If it is not and it should be, it will be encoded and the configuration file will be updated. Previously, there were times when the file was not being updated.
4. iCloud Account username/password changes - When the username/password is changed, the Apple account is logged into. If you select 'Save' the configuration file is updated. If you select 'Return', the updated username/password is not saved and the menu is displayed. This can lead to login problems the next time iCloud3 starts if you really wanted to save them but didn't. An additional Confirmation Screen is now displayed that lets you save them or not save them.

rc7 - Release Candidate 7 (10/15/2023)

rc7 - 10/15/2023
...............................
1. yaml Zones - Fixed a problem where zones configured using yaml were not being loaded when iCloud3 started.
2. Zone-Devices Count - New feature - The number of the devices within a zone is displayed with the tracking results on the Event Log. The counts are the numbers (x) after the zone name. For Example:
2. Stationary Zones - Minor changes to the handling of deleting a stationary zone when all devices had exited from it.
3. Zone-Devices Count - New feature - The number of the devices within a zone is displayed with the tracking results on the Event Log. The counts are the numbers (x) after the zone name. For Example:
_Zone > Away (2) > Home-2.45km, IndRivShores-6.53km, School-8.47km (1), Publix-10.3km, ThePoint-11.0km, Quail-12.0km, Warehouse-16.5km (1), GPS-(/±47m)_

An item is also posted to the Event Log when another device changes it's zone:
_Zone-Device Counts > Home (4), School (1), Warehouse (1)_

3. Stationary Zones - Minor changes to the handling of deleting a stationary zone when all devices had exited from it.

rc6 - Release Candidate 6 (10/7/2023)
...............................
Expand Down
203 changes: 125 additions & 78 deletions custom_components/icloud3/config_flow.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion custom_components/icloud3/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

VERSION = '3.0.rc7.1'
VERSION = '3.0.rc8'

DOMAIN = 'icloud3'
ICLOUD3 = 'iCloud3'
Expand Down
8 changes: 5 additions & 3 deletions custom_components/icloud3/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class iCloud3_Device(TrackerEntity):
def __init__(self, devicename, conf_device):
self.conf_device = conf_device
self.devicename = devicename
self.dr_device_id = '' # ha device_registry device_id
self.ha_device_id = '' # ha device_registry device_id
self.fname = devicename.title()

self.StatZone = None # The StatZone this Device is in or None if not in a StatZone
Expand Down Expand Up @@ -149,6 +149,8 @@ def initialize(self):

# Trigger & Update variables
self.trigger = 'iCloud3'
self.interval_secs = 0
self.interval_str = ''
self.next_update_secs = 0
self.seen_this_device_flag = False
self.iosapp_zone_enter_secs = 0
Expand Down Expand Up @@ -430,8 +432,8 @@ def _link_device_entities_sensor_device_tracker(self):
self.DeviceTracker = Gb.DeviceTrackers_by_devicename[self.devicename]
self.DeviceTracker.Device = self
try:
self.DeviceTracker.device_id = Gb.dr_device_id_by_devicename[self.devicename]
self.DeviceTracker.area_id = Gb.dr_area_id_by_devicename[self.devicename]
self.DeviceTracker.device_id = Gb.ha_device_id_by_devicename[self.devicename]
self.DeviceTracker.area_id = Gb.ha_area_id_by_devicename[self.devicename]
except:
pass

Expand Down
54 changes: 27 additions & 27 deletions custom_components/icloud3/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
area_reg = ar.async_get(hass)
Gb.area_id_personal_device = area_reg.async_get_or_create('Personal Device').id

_get_dr_device_ids_from_device_registry(hass)
_get_ha_device_ids_from_device_registry(hass)

if (ICLOUD3 in Gb.dr_area_id_by_devicename
and Gb.dr_area_id_by_devicename[ICLOUD3] in [None, 'unknown', '']):
if (ICLOUD3 in Gb.ha_area_id_by_devicename
and Gb.ha_area_id_by_devicename[ICLOUD3] in [None, 'unknown', '']):
_update_icloud3_integration_area_id()

except Exception as err:
Expand Down Expand Up @@ -111,11 +111,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e

if NewDeviceTrackers != []:
async_add_entities(NewDeviceTrackers, True)
_get_dr_device_ids_from_device_registry(hass)
_get_ha_device_ids_from_device_registry(hass)
_HA_LOGGER.info(f"iCloud3 Device Tracker entities: {Gb.device_trackers_cnt}")

Devices_no_area = [Device for Device in Gb.DeviceTrackers_by_devicename.values() \
if Device.dr_area_id in [None, 'unknown', '']]
if Device.ha_area_id in [None, 'unknown', '']]

if Devices_no_area != []:
for Device in Devices_no_area:
Expand All @@ -131,7 +131,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
log_error_msg(log_msg)

#-------------------------------------------------------------------------------------------
def _get_dr_device_ids_from_device_registry(hass):
def _get_ha_device_ids_from_device_registry(hass):
'''
Cycle thru the ha device registry, extract the iCloud3 entries and associate the
ha device_id with the ic3_devicename parameters
Expand All @@ -144,12 +144,12 @@ def _get_dr_device_ids_from_device_registry(hass):
icloud3_dev_reg = {device: device_entry for device, device_entry in dev_reg.deleted_devices.items()
if _icloud3_dev_reg_item(device_entry)}
for device, device_entry in icloud3_dev_reg.items():
_get_dr_device_id_from_device_entry(hass, device, device_entry)
_get_ha_device_id_from_device_entry(hass, device, device_entry)

icloud3_dev_reg = {device: device_entry for device, device_entry in dev_reg.devices.items()
if _icloud3_dev_reg_item(device_entry)}
for device, device_entry in icloud3_dev_reg.items():
_get_dr_device_id_from_device_entry(hass, device, device_entry)
_get_ha_device_id_from_device_entry(hass, device, device_entry)

except Exception as err:
log_exception(err)
Expand All @@ -167,7 +167,7 @@ def _icloud3_dev_reg_item(device_entry):
return False

#-------------------------------------------------------------------------------------------
def _get_dr_device_id_from_device_entry(hass, device, device_entry):
def _get_ha_device_id_from_device_entry(hass, device, device_entry):
'''
For each entry in the device registry, determine if it is an iCloud3 entry (iCloud3 is in
the device_entry.identifiers field. If so, check the other items, determine if one is a
Expand All @@ -188,8 +188,8 @@ def _get_dr_device_id_from_device_entry(hass, device, device_entry):
'''
try:
if device_entry.name in [DOMAIN, ICLOUD3, 'iCloud3 Integration']:
Gb.dr_device_id_by_devicename[ICLOUD3] = device_entry.id
Gb.dr_area_id_by_devicename[ICLOUD3] = device_entry.area_id
Gb.ha_device_id_by_devicename[ICLOUD3] = device_entry.id
Gb.ha_area_id_by_devicename[ICLOUD3] = device_entry.area_id
return
except:
pass
Expand All @@ -200,8 +200,8 @@ def _get_dr_device_id_from_device_entry(hass, device, device_entry):

for item in de_identifiers:
if item in Gb.conf_devicenames:
Gb.dr_device_id_by_devicename[item] = device_entry.id
Gb.dr_area_id_by_devicename[item] = device_entry.area_id
Gb.ha_device_id_by_devicename[item] = device_entry.id
Gb.ha_area_id_by_devicename[item] = device_entry.area_id
return

except Exception as err:
Expand All @@ -214,11 +214,11 @@ def _update_icloud3_integration_area_id():
try:
kwargs = {}
kwargs['area_id'] = Gb.area_id_personal_device
Gb.dr_area_id_by_devicename[ICLOUD3] = Gb.area_id_personal_device
Gb.ha_area_id_by_devicename[ICLOUD3] = Gb.area_id_personal_device

device_id = Gb.dr_device_id_by_devicename[ICLOUD3]
ha_device_id = Gb.ha_device_id_by_devicename[ICLOUD3]
device_registry = dr.async_get(Gb.hass)
dr_entry = device_registry.async_update_device(device_id, **kwargs)
dr_entry = device_registry.async_update_device(ha_device_id, **kwargs)

log_debug_msg( "Device Tracker entity changed: device_tracker.icloud3, "
"iCloud3, Personal Device")
Expand All @@ -238,9 +238,9 @@ def __init__(self, devicename, conf_device, data=None):
self.devicename = devicename
self.Device = None # Filled in after Device object has been created in start_ic3
self.entity_id = f"device_tracker.{devicename}"
self.dr_device_id = Gb.dr_device_id_by_devicename.get(self.devicename)
self.dr_area_id = Gb.dr_area_id_by_devicename.get(self.devicename)
# if self.dr_area_id in ['unknown', '']: self_area_id = None
self.ha_device_id = Gb.ha_device_id_by_devicename.get(self.devicename)
self.ha_area_id = Gb.ha_area_id_by_devicename.get(self.devicename)
# if self.ha_area_id in ['unknown', '']: self_area_id = None

self.device_fname = conf_device[FNAME]
self.device_type = conf_device[CONF_DEVICE_TYPE]
Expand Down Expand Up @@ -298,8 +298,8 @@ def get_device_id(self):
@property
def get_area_id(self):
"""Return the area_id of the device."""
# if self.dr_area_id is None:
# self.dr_area_id = Gb.dr_area_id_by_devicename[self.devicename] = \
# if self.ha_area_id is None:
# self.ha_area_id = Gb.ha_area_id_by_devicename[self.devicename] = \
# Gb.area_id_personal_device
return self.area_id

Expand Down Expand Up @@ -479,22 +479,22 @@ def _get_attribute_value(self, attribute):
def update_entity_attribute(self, new_fname=None, area_id=None):
""" Update entity definition attributes """

device_id = Gb.dr_device_id_by_devicename.get(self.devicename)
if device_id is None:
ha_device_id = Gb.ha_device_id_by_devicename.get(self.devicename)
if ha_device_id is None:
return

if new_fname is None and area_id is None:
return

try:
area_id = area_id or self.dr_area_id or Gb.area_id_personal_device
area_id = area_id or self.ha_area_id or Gb.area_id_personal_device
area_reg = ar.async_get(Gb.hass)
area_name = area_reg.async_get_area(area_id).name
except:
area_id = area_name = None

self.device_fname = new_fname or self.device_fname
self.dr_area_id = Gb.dr_area_id_by_devicename[self.devicename] = \
self.ha_area_id = Gb.ha_area_id_by_devicename[self.devicename] = \
area_id

log_debug_msg(f"Device Tracker entity changed: device_tracker.{self.devicename}, "
Expand Down Expand Up @@ -533,10 +533,10 @@ def update_entity_attribute(self, new_fname=None, area_id=None):
kwargs = {}
kwargs['name'] = f"{self.device_fname} ({self.devicename})"
kwargs['name_by_user'] = ""
kwargs['area_id'] = self.dr_area_id
kwargs['area_id'] = self.ha_area_id

device_registry = dr.async_get(Gb.hass)
dr_entry = device_registry.async_update_device(self.dr_device_id, **kwargs)
dr_entry = device_registry.async_update_device(self.ha_device_id, **kwargs)

#-------------------------------------------------------------------------------------------
def remove_device_tracker(self):
Expand Down
4 changes: 2 additions & 2 deletions custom_components/icloud3/global_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ class GlobalVariables(object):
Sensors_by_devicename = {} # HA sensor.[devicename]_[sensor_name]_[from_zone] objects
Sensors_by_devicename_from_zone = {} # HA sensor.[devicename]_[sensor_name]_[from_zone] objects
Sensor_EventLog = None # Event Log sensor object
dr_device_id_by_devicename = {} # HA device_registry device_id
dr_area_id_by_devicename = {} # HA device_registry area_id
ha_device_id_by_devicename = {} # HA device_registry device_id
ha_area_id_by_devicename = {} # HA device_registry area_id

# Event Log operational fields
evlog_card_directory = ''
Expand Down
11 changes: 11 additions & 0 deletions custom_components/icloud3/helpers/time_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ def secs_to_time_str(secs):

return time_str

#--------------------------------------------------------------------
def secs_to_hrs_str(secs):
if secs < 1:
return '0 hrs'
else:
return f"{secs/3600:.1f} hrs"

#--------------------------------------------------------------------
def mins_to_time_str(mins):
""" Create the time string from seconds """
Expand Down Expand Up @@ -446,6 +453,10 @@ def format_age(secs):

return f"{secs_to_time_str(secs)} ago"

#--------------------------------------------------------------------
def format_age_hrs(secs):
return f"{secs_to_hrs_str(secs_since(secs))} ago"

#--------------------------------------------------------------------
def format_age_ts(time_secs):
if time_secs < 1:
Expand Down
6 changes: 4 additions & 2 deletions custom_components/icloud3/icloud3_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ def _main_5sec_loop_update_tracked_devices_iosapp(self, Device):
post_event(devicename, event_msg)
return

# If the iOS App is the primary data source next_update time is reached, get the
# If the iOS App is the primary and data source next_update time is reached, get the
# old location threshold. Send a location request to the iosapp device if the
# data is older than the threshold, the next_update is newer than the iosapp data
# and the next_update and data time is after the last request was sent.
Expand Down Expand Up @@ -407,7 +407,9 @@ def _main_5sec_loop_update_tracked_devices_iosapp(self, Device):
event_msg = f"Trigger > {Device.iosapp_data_change_reason}"
post_event(devicename, event_msg)

# If entering a zone, check the passthru time, exit if it is now set
# If using the passthru zone delay:
# If entering a zone, set it if it is not set
# If exiting, reset it
if Gb.is_passthru_zone_used:
if instr(Device.iosapp_data_change_reason, ENTER_ZONE):
if Device.set_passthru_zone_delay(IOSAPP,
Expand Down
4 changes: 2 additions & 2 deletions custom_components/icloud3/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ def __init__(self, devicename, sensor_base, conf_device, from_zone=None):

self.entity_name = f"{devicename}_{self.sensor}"
self.entity_id = f"sensor.{self.entity_name}"
self.device_id = Gb.dr_device_id_by_devicename.get(ICLOUD3)
self.device_id = Gb.ha_device_id_by_devicename.get(ICLOUD3)

self.Device = Gb.Devices_by_devicename.get(devicename)
if self.Device and from_zone:
Expand Down Expand Up @@ -1158,7 +1158,7 @@ def __init__(self, fname, entity_name):
self.entity_id = f"sensor.{self.entity_name}"
self._unsub_dispatcher = None
self._device = DOMAIN
# self.ic3_device_id = Gb.ic3_device_id = Gb.dr_device_id_by_devicename.get(DOMAIN)
# self.ic3_device_id = Gb.ic3_device_id = Gb.ha_device_id_by_devicename.get(DOMAIN)
self.current_state_value = ''
self.history_exclude_flag = True

Expand Down
Loading

0 comments on commit c42a05a

Please sign in to comment.