Skip to content

Commit

Permalink
iCloud3 v3.0.5.2 (6/8/2024)
Browse files Browse the repository at this point in the history
  • Loading branch information
gcobb321 committed Jun 8, 2024
1 parent 3c3ac9c commit 3a6c63a
Show file tree
Hide file tree
Showing 28 changed files with 408 additions and 284 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

[![CurrentVersion](https://img.shields.io/badge/Current_Version-v3.0.5-blue.svg)](https://github.com/gcobb321/icloud3_v3) [![Type](https://img.shields.io/badge/Type-Custom_Component-orange.svg)](https://github.com/gcobb321/icloud3_v3) [![HACS](https://img.shields.io/badge/HACS-Custom_Repository-orange.svg)](https://github.com/gcobb321/icloud3_v3)

[![ProjectStage](https://img.shields.io/badge/Project_Stage-Development_Version-forestgreen.svg)](https://github/gcobb321/icloud3_v3) [![Released](https://img.shields.io/badge/Released-May,_2024-forestgreen.svg)](https://github.com/gcobb321/icloud3_v3)
[![ProjectStage](https://img.shields.io/badge/Project_Stage-Development_Version-forestgreen.svg)](https://github/gcobb321/icloud3_v3) [![Released](https://img.shields.io/badge/Released-June,_2024-forestgreen.svg)](https://github.com/gcobb321/icloud3_v3)



Expand Down
6 changes: 6 additions & 0 deletions custom_components/icloud3/ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
**Installing for the first time_** - See [here](https://gcobb321.github.io/icloud3_v3_docs/#/chapters/3.2-installing-and-configuring) for instructions on installing as a New Installation
**iCloud3 v3 Documentation** - iCloud3 User Guide can be found [here](https://gcobb321.github.io/icloud3_v3_docs/#/)

3.0.5.2
.......................
### Change Log - v3.0.5.2 (6/8/2024)
1. HA I/O ERROR FROM EVENT LOOP (Fixed) - HA was complaining about doing I/O (HACS file) outside of the Event Loop. Changed the method of doing I/O to use HA routines for the configuration file, restore state file and HACS file.
2. FROM_ZONE ERROR (Fixed) - Normally the TrackFrom Zone and NextUpdate Zone is the Home zone. Added a check to set it to Home if it had never been set.


3.0.5.1
.......................
Expand Down
1 change: 0 additions & 1 deletion custom_components/icloud3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
Gb.entry_id = entry.entry_id
Gb.operating_mode = MODE_INTEGRATION
Gb.PyiCloud = None
Gb.start_icloud3_inprocess_flag = True

start_ic3.initialize_directory_filenames()

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

VERSION = '3.0.5.1'
VERSION = '3.0.5.2'
VERSION_BETA = ''
#-----------------------------------------
DOMAIN = 'icloud3'
Expand Down
50 changes: 31 additions & 19 deletions custom_components/icloud3/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ def __init__(self, devicename, conf_device):
self.FromZone_Home = None # DeviceFmZone object for the Home zone
self.from_zone_names = [] # List of the from_zones in the FromZones_by_zone dictionary
self.only_track_from_home = True # Track from only Home (True) or also track from other zones (False)
self.FromZone_BeingUpdated = None # DeviceFmZone object being updated in determine_interval for EvLog TfZ info
self.FromZone_NextToUpdate = None # Set to the DeviceFmZone when it's next_update_time is reached
self.FromZone_BeingUpdated = None # DeviceFmZone object being updated in determine_interval for EvLog TfZ info
self.FromZone_NextToUpdate = None # Set to the DeviceFmZone when it's next_update_time is reached
self.FromZone_TrackFrom = None # DeviceFmZone object for the Closest tfz - used to set the Device's sensors
self.FromZone_LastIn = None # DeviceFmZone object the device was last in
self.TrackFromBaseZone = None # DeviceFmZone of Home or secondary tracked from zone
Expand Down Expand Up @@ -572,8 +572,8 @@ def initialize_non_tracking_config_fields(self, conf_device):
self.sensors[PICTURE] = picture if instr(picture, '/') else (f"/local/{picture}")
self.sensor_badge_attrs[PICTURE] = self.sensors[PICTURE]

self.statzone_inzone_interval_secs = min(self.inzone_interval_secs, Gb.statzone_inzone_interval_secs)
self.inzone_interval_secs = conf_device.get(CONF_INZONE_INTERVAL, 30) * 60
self.statzone_inzone_interval_secs = min(self.inzone_interval_secs, Gb.statzone_inzone_interval_secs)
self.fixed_interval_secs = conf_device.get(CONF_FIXED_INTERVAL, 0) * 60
self.device_type = conf_device.get(CONF_DEVICE_TYPE, 'iphone')
self.log_zones = conf_device.get(CONF_LOG_ZONES, ['none'])
Expand Down Expand Up @@ -696,9 +696,11 @@ def _validate_zone_parameters(self):
self.conf_device[CONF_TRACK_FROM_ZONES] = list_del(self.conf_device[CONF_TRACK_FROM_ZONES], zone)

# Check log-zone-activity
if self.conf_device[CONF_LOG_ZONES] in ['', []]:
self.conf_device[CONF_LOG_ZONES] = ['none']
lza_zones += "Initialized"
if (self.conf_device[CONF_LOG_ZONES] in ['', []]
or (len(self.conf_device[CONF_LOG_ZONES]) == 1
and self.conf_device[CONF_LOG_ZONES][0].startswith('name-'))):
self.conf_device[CONF_LOG_ZONES] = self.log_zones = ['none']

for zone in self.conf_device[CONF_LOG_ZONES].copy():
if zone.startswith('name-') or zone == 'none':
continue
Expand Down Expand Up @@ -1471,7 +1473,8 @@ def set_passthru_zone_delay(self, data_source, zone_entered=None, zone_entered_s
passthru_not_used_reason = 'Timer Expired'

if passthru_not_used_reason:
post_event(self.devicename, f"Zone Enter Not Delayed > {passthru_not_used_reason}")
post_event(self.devicename,
f"Zone Enter Not Delayed > {passthru_not_used_reason}")
return False

# Activate Passthru zone
Expand All @@ -1480,14 +1483,14 @@ def set_passthru_zone_delay(self, data_source, zone_entered=None, zone_entered_s
self.passthru_zone_timer = Gb.this_update_secs + Gb.passthru_zone_interval_secs
self.passthru_zone = zone_entered

event_msg =(f"Enter Zone Delayed > {zone_dname(self.passthru_zone)}, "
post_event(self.devicename,
f"Enter Zone Delayed > {zone_dname(self.passthru_zone)}, "
f"DelayFor-{format_timer(Gb.passthru_zone_interval_secs)}")
post_event(self.devicename, event_msg)

info_msg = (f"Enter Zone Delayed - {zone_dname(self.passthru_zone)}, "
self.display_info_msg(
f"Enter Zone Delayed - {zone_dname(self.passthru_zone)}, "
f"Expires-{secs_to_time(self.passthru_zone_timer)} "
f"({format_timer(secs_to(self.passthru_zone_timer))})")
self.display_info_msg(info_msg)

return True

Expand Down Expand Up @@ -1521,6 +1524,15 @@ def is_next_update_time_reached(self):
if self.icloud_initial_locate_done is False or self.is_tracking_resumed:
return True

if self.FromZone_NextToUpdate is None:
FromZone = self.FromZone_Home
self.FromZone_LastIn = FromZone
self.FromZone_BeingUpdated = FromZone
self.FromZone_NextToUpdate = FromZone
self.FromZone_TrackFrom = FromZone
self.TrackFromBaseZone = FromZone
self.last_track_from_zone = FromZone.from_zone

return Gb.this_update_secs >= self.FromZone_NextToUpdate.next_update_secs

#
Expand Down Expand Up @@ -1813,16 +1825,15 @@ def is_location_data_rejected(self):
elif self.loc_data_ispoorgps:
reason_msg = (f"PoorGPS>{Gb.gps_accuracy_threshold}m")

event_msg =(f"Rejected #{self.old_loc_cnt} > "
post_event(self.devicename,
f"Rejected #{self.old_loc_cnt} > "
f"{self.dev_data_source}-{self.loc_data_time_gps}, "
f"{format_age(self.loc_data_secs)}, "
f"{reason_msg}, "
f"NextUpdate-{secs_to_time(self.next_update_secs)} "
f"({format_timer(interval)}), "
f"LastUpdate-{format_age(self.last_update_loc_secs)}")

post_event(self.devicename, event_msg)

except Exception as err:
log_exception(err)

Expand Down Expand Up @@ -1984,8 +1995,8 @@ def display_battery_info_msg(self, force_display=False):
self.last_battery_msg = battery_msg
self.last_battery_msg_secs = time_now_secs()

event_msg = f"Battery Info > Level-{battery_msg} ({self.dev_data_battery_source})"
post_event(self.devicename, event_msg)
post_event(self.devicename,
f"Battery Info > Level-{battery_msg} ({self.dev_data_battery_source})")

if Gb.EvLog.evlog_attrs["devicename"] == self.devicename:
Gb.EvLog.update_event_log_display(self.devicename)
Expand Down Expand Up @@ -2108,10 +2119,10 @@ def display_update_location_msg(self):
return

if self.isnotin_zone or self.loc_data_dist_moved_km > .015:
event_msg =(f"Selected > "
post_event(self.devicename,
f"Selected > "
f"{self.last_loc_data_time_gps}"
f"{RARROW}{self.dev_data_source}-{self.loc_data_time_gps}")
post_event(self.devicename,event_msg)

#self.last_loc_data_time_gps = f"{self.dev_data_source}-{self.loc_data_time_gps} "

Expand Down Expand Up @@ -2162,7 +2173,8 @@ def update_sensor_values_from_data_fields(self):
self.sensors[MOVED_TIME_TO] = self.loc_data_time_moved_to
self.sensors[ZONE_DATETIME] = secs_to_datetime(self.zone_change_secs)

if self.FromZone_NextToUpdate is None: self.FromZone_NextToUpdate = self.FromZone_Home
if self.FromZone_NextToUpdate is None:
self.FromZone_NextToUpdate = self.FromZone_Home
self.interval_secs = self.FromZone_NextToUpdate.interval_secs
self.interval_str = self.FromZone_NextToUpdate.interval_str
self.next_update_secs = self.FromZone_NextToUpdate.next_update_secs
Expand Down
Binary file not shown.
4 changes: 2 additions & 2 deletions custom_components/icloud3/global_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ class GlobalVariables(object):

# System Wide variables control iCloud3 start/restart procedures
polling_5_sec_loop_running = False # Indicates the 5-sec polling loop is set up
start_icloud3_inprocess_flag = False
initial_icloud3_loading_flag = True
start_icloud3_inprocess_flag = True
restart_icloud3_request_flag = False # iC3 needs to be restarted
restart_ha_flag = False # HA needs to be restarted
any_device_was_updated_reason = ''
Expand All @@ -203,7 +204,6 @@ class GlobalVariables(object):
get_FAMSHR_devices_retry_cnt = 0 # Retry count to connect to iCloud and retrieve FamShr devices
reinitialize_icloud_devices_flag= False # Set when no devices are tracked and iC3 needs to automatically restart
reinitialize_icloud_devices_cnt = 0
initial_icloud3_loading_flag = False

# Debug and trace flags
log_debug_flag = False
Expand Down
91 changes: 90 additions & 1 deletion custom_components/icloud3/helpers/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
from ..global_variables import GlobalVariables as Gb
from ..const import (NOT_HOME, STATIONARY, CIRCLE_LETTERS_DARK, UNKNOWN, CRLF_DOT, CRLF, )
from collections import OrderedDict
from homeassistant.util import json as json_util
from homeassistant.helpers import json as json_helpers
import os
import json
import logging
_LOGGER = logging.getLogger(__name__)
#_LOGGER = logging.getLogger(f"icloud3")

#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#
Expand Down Expand Up @@ -274,6 +280,90 @@ def format_list(arg_list):
def format_cnt(desc, n):
return f", {desc}(#{n})" if n > 1 else ''

#--------------------------------------------------------------------
async def async_load_json_file(filename):
if os.path.exists(filename) is False:
return {}

try:
data = await Gb.hass.async_add_executor_job(
json_util.load_json,
filename)
return data

except Exception as err:
#_LOGGER.exception(err)
pass

return {}

#--------------------------------------------------------------------
def load_json_file(filename):
if os.path.exists(filename) is False:
return {}

try:
if Gb.initial_icloud3_loading_flag:
data = json_util.load_json(filename)
else:
data = Gb.hass.async_add_executor_job(
json_util.load_json,
filename)
return data

except RuntimeError as err:
if str(err) == 'no running event loop':
data = json_util.load_json(filename)
return data

except Exception as err:
_LOGGER.exception(err)
pass

return {}

#--------------------------------------------------------------------
async def async_save_json_file(filename, data):

try:
await Gb.hass.async_add_executor_job(
json_helpers.save_json,
filename,
data)
return True

except Exception as err:
_LOGGER.exception(err)
pass

return False

#--------------------------------------------------------------------
def save_json_file(filename, data):

try:
# The HA event loop has not been set up yet during initialization
if Gb.initial_icloud3_loading_flag:
json_helpers.save_json(filename, data)
else:

Gb.hass.async_add_executor_job(
json_helpers.save_json,
filename,
data)
return True

except RuntimeError as err:
if err == 'no running event loop':
json_helpers.save_json(filename, data)
return True

except Exception as err:
_LOGGER.exception(err)
pass

return False

#--------------------------------------------------------------------
def delete_file(file_desc, directory, filename, backup_extn=None, delete_old_sv_file=False):
'''
Expand Down Expand Up @@ -401,4 +491,3 @@ def base64_decode(string):
base64_bytes = string.encode('ascii')
string_bytes = base64.b64decode(base64_bytes)
return string_bytes.decode('ascii')

18 changes: 1 addition & 17 deletions custom_components/icloud3/helpers/messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,23 +507,7 @@ def log_start_finish_update_banner(start_finish, devicename,

log_info_msg(log_msg)

#--------------------------------------------------------------------
def write_debug_log(debug_log_title=None):
'''
Cycle thru the debug_log and write all items to the icloud2-0.log file
'''
if Gb.log_debug_flag is False or Gb.debug_log == {}: return

if debug_log_title:
log_debug_msg(f"{format_header_box(debug_log_title)}")

for field, values in Gb.debug_log.items():
log_debug_msg(f"{field}={values}")

if debug_log_title:
log_debug_msg(f"{format_header_box(debug_log_title)}")

Gb.debug_log = {}

#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#
Expand Down Expand Up @@ -574,7 +558,7 @@ def filter_special_chars(recd, evlog_export=False):
recd = recd.replace(NBSP6, ' ')
recd = recd.strip()
recd = recd.replace(CRLF, f"\n{indent}")
recd = recd.replace('◦', f" ◦")
recd = recd.replace('◦', f" ◦")
recd = recd.replace('* >', '')
recd = recd.replace('&lt;', '<')

Expand Down
2 changes: 1 addition & 1 deletion custom_components/icloud3/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
"issue_tracker": "https://github.com/gcobb321/icloud3_v3/issues",
"loggers": ["icloud3"],
"requirements": [],
"version": "3.0"
"version": "3.0.5.2"
}
Loading

0 comments on commit 3a6c63a

Please sign in to comment.