Skip to content

Commit

Permalink
iCloud3 v3.0.rc6
Browse files Browse the repository at this point in the history
  • Loading branch information
gcobb321 committed Oct 10, 2023
1 parent d1dc7cc commit 7a8a59f
Show file tree
Hide file tree
Showing 16 changed files with 257 additions and 237 deletions.
10 changes: 8 additions & 2 deletions custom_components/icloud3/ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
pr1.5
rc6 - Release Candidate 6 (10/7/2023)
...............................
1. Bug Fix - Fixed the error causing the "AttributeError: 'iCloud3_Device' object has no attribute 'interval_secs' message at line 680, in determine_interval_after_error" error.
2. China Users - Added an option to the Configure Settings - iCloud Account & iOS App Data Sources screen to enable the '.cn. Apple Web Server URL address suffix
2. China Users - Added an option to the Configure Settings - iCloud Account & iOS App Data Sources screen to enable the '.cn. Apple Web Server URL address suffix.
3. Monitored Devices - The iOSApp state value is no longer displayed on the Event Log if it is different than the iCloud3 zone and it is earlier the last FamShr update time since it is old and is probably incorrect.
4. iCloud3 Version - The version that is currently running is now displayed in the Configure Settings menu screen and more clearly on Event Log messages during startup.
5. Battery - HA has changed the battery 'state class' internal value from 'battery' to 'measurement'.
6. Prerelease Version number - This has changed to Release Candidate number to better conform to HA standards. Version pr1.5 was a developer test version and not released.
7. Configure Setting - Made some minor menu text changes for consistency.



pr1.4
Expand Down
18 changes: 9 additions & 9 deletions custom_components/icloud3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
config_file.load_storage_icloud3_configuration_file()

if Gb.conf_profile[CONF_VERSION] == 1:
_HA_LOGGER.info(f"Initializing iCloud3 {VERSION} - Remove Platform: iCloud3 statement")
_HA_LOGGER.info(f"Initializing iCloud3 v{VERSION} - Remove Platform: iCloud3 statement")

except Exception as err:
log_exception(err)
Expand All @@ -91,9 +91,9 @@ async def start_icloud3(event=None):
icloud3_started = await Gb.hass.async_add_executor_job(Gb.iCloud3.start_icloud3)

if icloud3_started:
log_info_msg(f"iCloud3 {Gb.version} started")
log_info_msg(f"iCloud3 v{Gb.version} started")
else:
log_error_msg(f"iCloud3 {Gb.version} Initialization Failed")
log_error_msg(f"iCloud3 v{Gb.version} Initialization Failed")

#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><><><><><><><><><>
#
Expand Down Expand Up @@ -140,8 +140,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):

Gb.evlog_btnconfig_url = Gb.conf_profile[CONF_EVLOG_BTNCONFIG_URL].strip()
Gb.evlog_version = Gb.conf_profile['event_log_version']
Gb.EvLog = event_log.EventLog(Gb.hass)
log_info_msg(f"Setting up iCloud3 {VERSION} - Using Integration method")
Gb.EvLog = event_log.EventLog(Gb.hass)
log_info_msg(f"Setting up iCloud3 v{VERSION} - Using Integration method")

Gb.start_icloud3_inprocess_flag = True

Expand Down Expand Up @@ -185,8 +185,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
# SETUP PROCESS TO START ICLOUD3
#
#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Gb.EvLog.display_user_message('iCloud3 is Starting')
Gb.EvLog.post_event(f"{EVLOG_IC3_STARTING}Initializing iCloud3 v{Gb.version} > "
Gb.EvLog.display_user_message(f"Starting iCloud3 v{Gb.version}")
Gb.EvLog.post_event(f"{EVLOG_IC3_STARTING}iCloud3 v{Gb.version} > Starting, "
f"{dt_util.now().strftime('%A, %b %d')}")

Gb.iCloud3 = iCloud3()
Expand All @@ -210,9 +210,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
icloud3_started = await Gb.hass.async_add_executor_job(Gb.iCloud3.start_icloud3)

if icloud3_started:
log_info_msg(f"iCloud3 {Gb.version} started")
log_info_msg(f"iCloud3 v{Gb.version} started")
else:
log_error_msg(f"iCloud3 {Gb.version} Initialization Failed")
log_error_msg(f"iCloud3 v{Gb.version} Initialization Failed")

return True

Expand Down
208 changes: 105 additions & 103 deletions custom_components/icloud3/config_flow.py

Large diffs are not rendered by default.

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

VERSION = '3.0.pr1.5'
VERSION = '3.0.rc6'

DOMAIN = 'icloud3'
ICLOUD3 = 'iCloud3'
Expand Down Expand Up @@ -245,7 +245,7 @@
lite_circled_letters = "Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ"
dark_circled_letters = "🅐 🅑 🅒 🅓 🅔 🅕 🅖 🅗 🅘 🅙 🅚 🅛 🅜 🅝 🅞 🅟 🅠 🅡 🅢 🅣 🅤 🅥 🅦 🅧 🅨 🅩 ✪"
Symbols = ±▪•●▬⮾ ⊗ ⊘✓×ø¦ ▶◀ ►◄▲▼ ∙▪ »« oPhone=►▶→⟾➤➟➜➔➤🡆🡪🡺⟹🡆➔ᐅ◈🝱☒☢⛒❌⊘Ɵ⊗ⓧⓍ⛒🜔
— – ⁃ » ━▶ ━➤🡺 —> > > ❯↦ … 🡪ᗕ ᗒ ᐳ ─🡢 ──ᗒ 🡢 ─ᐅ ↣ ➙ →《》◆◈◉●▐‖ ▹▻▷◁◅◃▶➤➜➔❰❰❱❱ ⠤
— – ⁃ » ━▶ ━➤🡺 —> > > ❯↦ … 🡪ᗕ ᗒ ᐳ ─🡢 ──ᗒ 🡢 ─ᐅ ↣ ➙ →《》◆◈◉●▐‖ ▹▻▷◁◅◃▶➤➜➔❰❰❱❱ ⠤
⣇⠈⠉⠋⠛⠟⠿⡿⣿ https://www.fileformat.info/info/unicode/block/braille_patterns/utf8test.htm
'''
NBSP = '⠈' #'&nbsp;'
Expand Down Expand Up @@ -703,6 +703,8 @@
MOVED_TIME_FROM = 'moved_from'
MOVED_TIME_TO = 'moved_to'

# TfZ Sensors are not configured via config_flow but built in
# config_flow from the distance, time & zone sensors
CONF_SENSORS_TRACK_FROM_ZONES = 'track_from_zones'
TFZ_ZONE_INFO = 'tfz_zone_info'
TFZ_DISTANCE = 'tfz_distance'
Expand Down
7 changes: 6 additions & 1 deletion custom_components/icloud3/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,11 @@ def format_info_msg(self):
# if self.dev_data_battery_level > 0:
# info_msg += f"Battery-{self.format_battery_level}, "

if (self.iosapp_monitor_flag
and secs_since(self.iosapp_data_secs) > 3600):
info_msg += (f"iOSApp LastUpdate-"
f"{secs_to_age_str(self.iosapp_data_secs)}, ")

if self.is_gps_poor:
info_msg += (f"PoorGPS-±{self.loc_data_gps_accuracy}m "
f"#{self.old_loc_poor_gps_cnt}")
Expand All @@ -2082,7 +2087,7 @@ def format_info_msg(self):
except Exception as err:
log_exception(err)

self.info_msg = 'iCloud3 Started' if info_msg == '' else info_msg[:-2]
self.info_msg = f'iCloud3 v{Gb.version} > Started' if info_msg == '' else info_msg[:-2]
return self.info_msg

#-------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions custom_components/icloud3/global_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class GlobalVariables(object):
TrackedZones_by_zone = {HOME, None} # Tracked zones object by zone name set up with Devices.DeviceFmZones object
ActiveZones = [] # Active Zones - Not passive, radius > 0
StatZones = [] # Stationary Zone objects
StatZones_to_delete = [] # Stationary Zone to delete after the devices that we're in it have been updated
StatZones_by_zone = {} # Stationary Zone objects by their id number (1-10 --> ic3_#_stationary)
HomeZone = None # Home Zone object

Expand Down
40 changes: 16 additions & 24 deletions custom_components/icloud3/icloud3_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ def start_icloud3(self):

start_ic3_control.stage_3_setup_configured_devices()
stage_4_success = start_ic3_control.stage_4_setup_data_sources()

if stage_4_success is False:
start_ic3_control.stage_4_setup_data_sources(retry=True)

Expand Down Expand Up @@ -307,19 +308,15 @@ def _polling_loop_5_sec_device(self, ha_timer_secs):
Gb.trace_prefix = 'WRAPUP > '

#<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>
# UPDATE DISPLAYED DEVICE INFO FIELD
# POST UPDATE LOOP TASKS
#<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>
# Update the EvLog display if the displayed device was updated after
# the last EvLog refresh
if Gb.log_debug_flag is False:
if Device := Gb.Devices_by_devicename.get(Gb.EvLog.devicename):
if Device.last_evlog_msg_secs > Gb.EvLog.last_refresh_secs:
Gb.EvLog.update_event_log_display(devicename=Device.devicename)
# show_one_screen=show_one_screen)

#<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>
# UPDATE DISTANCE TO DEVICES SENSORS
#<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>
# Update distance sensors (_zone/home.waze/calc_distace) to update the
# distance to each device
if Gb.dist_to_other_devices_update_sensor_list:
Expand All @@ -331,6 +328,14 @@ def _polling_loop_5_sec_device(self, ha_timer_secs):

Gb.dist_to_other_devices_update_sensor_list = set()

# Remove all StatZones from HA flagged for removal in StatZone module
# Removing them after all devices have been updated lets HA process the statzone 'leave'
# automation trigger associated with a device before the zone is deleted.
if Gb.StatZones_to_delete:
for StatZone in Gb.StatZones_to_delete:
StatZone.remove_ha_zone()
Gb.StatZones_to_delete = []

Gb.trace_prefix = ''


Expand All @@ -339,7 +344,6 @@ def _polling_loop_5_sec_device(self, ha_timer_secs):
# MAIN 5-SEC LOOP PROCESSING CONTROLLERS
#
#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

def _main_5sec_loop_update_tracked_devices_iosapp(self, Device):
'''
Update the device based on iOS App data
Expand All @@ -365,11 +369,6 @@ def _main_5sec_loop_update_tracked_devices_iosapp(self, Device):
post_event(devicename, event_msg)
return

# xxxxx
# if Device.isnot_set is False:
# Device.moved_since_last_update_km = \
# Device.distance_km(Device.iosapp_data_latitude, Device.iosapp_data_longitude)

# If the iOS App is the primary 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
Expand Down Expand Up @@ -425,22 +424,12 @@ def _main_5sec_loop_update_tracked_devices_iosapp(self, Device):
and is_statzone(Device.iosapp_zone_exit_zone)
and Device.StatZone
and Device.iosapp_zone_exit_dist_m < Device.StatZone.radius_m):
# Device.iosapp_data_change_reason = (f"Relocate StatZone ("
# f"{zone_display_as(Device.iosapp_zone_exit_zone)})")
# event_msg =(f"Trigger Changed > {Device.iosapp_data_change_reason}, "
# f"Distance less than zone size")
xiosapp_data_change_reason = (f"XXXXX CANCELED Relocate StatZone ("
f"{zone_display_as(Device.iosapp_zone_exit_zone)})")

event_msg =(f"{EVLOG_ALERT}Trigger Changed > {xiosapp_data_change_reason}, "
f"Distance less than zone size "
f"{Device.StatZone.display_as} {Device.iosapp_zone_exit_dist_m} < {Device.StatZone.radius_m}")
post_event(devicename, event_msg)


# statzone.move_statzone_to_device_location(Device,
# latitude=Device.loc_data_latitude,
# longitude=Device.loc_data_longitude)
# return
statzone.kill_and_recreate_unuseable_statzone(Device)

else:
Expand Down Expand Up @@ -545,6 +534,9 @@ def _main_5sec_loop_update_monitored_devices(self, Device):
if Device.loc_data_dist_moved_km < .05:
return

if Device.loc_data_latitude == 0:
return

Device.update_sensors_flag = True
Device.icloud_update_reason = 'Monitored Device Update'

Expand Down Expand Up @@ -1012,8 +1004,8 @@ def _determine_interval_and_next_update(self, Device):
det_interval.determine_TrackFrom_zone(Device)

# pr1.4
# If the location is old and an update it's being done (probably from an iosapp trigger),
# see if the error interval is greater than this update interval. Is it is, Reset the counter
# If the location is old and an update is being done (probably from an iosapp trigger),
# see if the error interval is greater than this update interval. Is it is, Reset the counter
if Device.old_loc_poor_gps_cnt > 8:
error_interval_secs, error_cnt, max_error_cnt = det_interval.get_error_retry_interval(Device)
if error_interval_secs > Device.interval_secs:
Expand Down
7 changes: 2 additions & 5 deletions custom_components/icloud3/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ def _create_track_from_zone_sensors(devicename, conf_device, sensors_list):
devicename_sensor_zone = f"{devicename}_{sensor}_{from_zone}"

if devicename_sensor_zone in excluded_sensors_list:
# Gb.sensors_created_cnt += 1
log_debug_msg(f"Sensor entity excluded: sensor.{devicename_sensor_zone}")
continue

Expand Down Expand Up @@ -508,8 +507,6 @@ def _get_extra_attributes(self, sensor):
if instr(_sensor_attr_name, ZONE_DISTANCE_M_EDGE):
extra_attrs[_sensor_attr_name] = _sensor_value

# if attr_units_flag == False:
# attr_units_flag = True
if Gb.um == 'mi':
extra_attrs['distance_units_(attributes)'] = 'mi'
if self._get_sensor_value(ZONE_DISTANCE_M):
Expand Down Expand Up @@ -899,7 +896,7 @@ def native_value(self):
return Gb.broadcast_info_msg

elif self.sensor_not_set:
return f"◈◈ Starting iCloud3 ◈◈"
return f"◈◈ Starting iCloud3 v{Gb.version} ◈◈"

else:
return self.sensor_value
Expand Down Expand Up @@ -1117,7 +1114,7 @@ def native_value(self):
@property
def extra_state_attributes(self):
extra_attrs = self._get_extra_attributes(self.sensor)
extra_attrs.update({'device_class': 'battery', 'state_class': 'battery'})
extra_attrs.update({'device_class': 'battery', 'state_class': 'measurement'})

return extra_attrs

Expand Down
41 changes: 19 additions & 22 deletions custom_components/icloud3/support/determine_interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,6 @@ def determine_interval(Device, FromZone):
interval_method += '+>180s'
interval_secs = 180

#15-sec interval_secs (close to zone) and may be going into a stationary zone,
#increase the interval
# elif interval_secs == 15 and Gb.this_update_secs >= Device.statzone_timer+45:
# interval_method += '+6.StatTimer+45'
# interval_secs = 30

#Turn off waze close to zone flag to use waze after leaving zone or getting more than 1km from it
if Gb.Waze.waze_close_to_zone_pause_flag:
if inzone_flag or calc_dist_from_zone_km >= 1:
Expand Down Expand Up @@ -362,7 +356,6 @@ def determine_interval(Device, FromZone):
# Use interval_secs if > StatZone interval unless the StatZone interval is the device's
# inzone interval
if Device.is_in_statzone:
#and Device.statzone_inzone_interval_secs >= interval_secs):
interval_method = "7.StatZone"
interval_secs = Device.statzone_inzone_interval_secs

Expand All @@ -373,8 +366,7 @@ def determine_interval(Device, FromZone):
interval_secs = Device.statzone_inzone_interval_secs
elif inzone_flag:
pass
# interval_method = f"7.inZoneMax"
# interval_secs = Gb.max_interval_secs / 2

else:
interval_method = f"7.Max"
interval_secs = Gb.max_interval_secs
Expand All @@ -395,13 +387,13 @@ def determine_interval(Device, FromZone):
if (_Device.FromZone_TrackFrom
and _Device.near_device_distance <= NEAR_DEVICE_DISTANCE
and next_update_secs < _Device.FromZone_TrackFrom.next_update_secs):

next_update_secs = _Device.FromZone_TrackFrom.next_update_secs
interval_secs = _Device.FromZone_TrackFrom.interval_secs
interval_str = _Device.FromZone_TrackFrom.interval_str
interval_method = f"{_Device.fname}"

except:
error_msg = f"User Monitor Results error > {_Device.devicename}, Zone-{_Device.FromZone_TrackFrom.from_zone}"
post_error_msg(error_msg)
pass

# Update all dates and other fields
Expand All @@ -425,7 +417,6 @@ def determine_interval(Device, FromZone):
except Exception as err:
sensor_msg = post_internal_error('Update FromZone Times', traceback.format_exc)


#--------------------------------------------------------------------------------
# if poor gps and moved less than 1km, redisplay last distances
if (Device.state_change_flag is False
Expand Down Expand Up @@ -453,6 +444,14 @@ def determine_interval(Device, FromZone):
and waze_dist_from_zone_km > FromZone.max_dist_km):
FromZone.max_dist_km = waze_dist_from_zone_km

if Device.iosapp_monitor_flag:
# If monitored and the iosapp state is before the last update, reset it since
# the iosapp is not really used for monitored devices
if (Device.is_monitored
and Device.iosapp_data_state != Device.loc_data_zone
and Device.last_update_loc_secs > (Device.iosapp_data_state_secs + Device.old_loc_threshold_secs)):
Device.iosapp_data_state = NOT_SET

#--------------------------------------------------------------------------------
#Make sure the new 'last state' value is the internal value for
#the state (e.g., Away-->not_home) to reduce state change triggers later.
Expand Down Expand Up @@ -533,10 +532,15 @@ def post_results_message_to_event_log(Device, FromZone):
if Device.is_monitored:
event_msg += f"{Device.dev_data_source}, "
if Gb.log_debug_flag and FromZone.interval_method and Device.is_tracked:
event_msg += (f"Method-{FromZone.interval_method}, "
event_msg += ( f"Method-{FromZone.interval_method}, "
f"{'Went3km, ' if Device.went_3km else ''}")
if Gb.Waze.waze_status == WAZE_OUT_OF_RANGE:
event_msg += "Waze-OverMaxDist, "
if (Device.iosapp_monitor_flag
and secs_since(Device.iosapp_data_secs) > 3600):
event_msg += ( f"iOSAppLastUpdate-"
f"{secs_to_age_str(Device.iosapp_data_secs)}, ")

post_event(Device.devicename, event_msg[:-2])

if True is True: #Device.is_tracked:
Expand Down Expand Up @@ -566,15 +570,8 @@ def post_zone_time_dist_event_msg(Device, FromZone):
Event Log
'''

iosapp_state = '──'
if Device.iosapp_monitor_flag:
iosapp_state = zone_display_as(Device.iosapp_data_state)
if (is_statzone(Device.iosapp_data_state)
and Device.iosapp_data_state != Device.loc_data_zone
and Device.iosapp_data_state not in statzone.ha_statzones()):
iosapp_state = f"🅧{iosapp_state}"

ic3_zone = zone_display_as(Device.loc_data_zone)
iosapp_state = zone_display_as(Device.iosapp_data_state)
ic3_zone = zone_display_as(Device.loc_data_zone)

if Device.loc_data_zone == NOT_SET:
interval_str = travel_time = distance = 0
Expand Down
Loading

0 comments on commit 7a8a59f

Please sign in to comment.