Skip to content

Commit

Permalink
2022.12.4
Browse files Browse the repository at this point in the history
- Revert to manual unit conversions
  • Loading branch information
craibo committed Dec 16, 2022
1 parent 6844d5e commit 6b30768
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 72 deletions.
25 changes: 17 additions & 8 deletions custom_components/ha_strava/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(self):
self._config_entry_title = None
self._import_strava_images = None
self._img_update_interval_seconds = None
self._config_distance_unit_override = None

async def show_form_init(self):
"""
Expand Down Expand Up @@ -102,6 +103,13 @@ async def show_form_init(self):
ha_strava_config_entries[0].data.get(CONF_PHOTOS),
),
): bool,
vol.Required(
CONF_DISTANCE_UNIT_OVERRIDE,
default=ha_strava_config_entries[0].options.get(
CONF_DISTANCE_UNIT_OVERRIDE,
CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT,
),
): vol.In(DISTANCE_UNIT_OVERRIDE_OPTIONS),
}
),
)
Expand Down Expand Up @@ -152,7 +160,12 @@ async def async_step_init(self, user_input=None):

self._nb_activities = user_input.get(CONF_NB_ACTIVITIES)
self._import_strava_images = user_input.get(CONF_PHOTOS)
self._img_update_interval_seconds = int(user_input.get(CONF_IMG_UPDATE_INTERVAL_SECONDS))
self._img_update_interval_seconds = int(
user_input.get(CONF_IMG_UPDATE_INTERVAL_SECONDS)
)
self._config_distance_unit_override = user_input.get(
CONF_DISTANCE_UNIT_OVERRIDE
)
self._config_entry_title = ha_strava_config_entries[0].title

ha_strava_options = { # pylint: disable=unnecessary-comprehension
Expand All @@ -164,6 +177,9 @@ async def async_step_init(self, user_input=None):
CONF_IMG_UPDATE_INTERVAL_SECONDS
] = self._img_update_interval_seconds
ha_strava_options[CONF_PHOTOS] = self._import_strava_images
ha_strava_options[
CONF_DISTANCE_UNIT_OVERRIDE
] = self._config_distance_unit_override

_LOGGER.debug(f"Strava Config Options: {ha_strava_options}")
return self.async_create_entry(
Expand All @@ -181,7 +197,6 @@ class OAuth2FlowHandler(
DOMAIN = DOMAIN
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_PUSH
_import_photos_from_strava = True
_distance_unit_override_metric = CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT

@property
def logger(self) -> logging.Logger:
Expand Down Expand Up @@ -209,10 +224,6 @@ async def async_step_get_oauth_info(self, user_input=None):
vol.Required(CONF_CLIENT_ID): str,
vol.Required(CONF_CLIENT_SECRET): str,
vol.Required(CONF_PHOTOS, default=self._import_photos_from_strava): bool,
vol.Required(
CONF_DISTANCE_UNIT_OVERRIDE,
default=self._distance_unit_override_metric
): vol.In(DISTANCE_UNIT_OVERRIDE_OPTIONS),
}

assert self.hass is not None
Expand All @@ -227,7 +238,6 @@ async def async_step_get_oauth_info(self, user_input=None):

if user_input is not None:
self._import_photos_from_strava = user_input[CONF_PHOTOS]
self._distance_unit_override_metric = user_input[CONF_DISTANCE_UNIT_OVERRIDE]
config_entry_oauth2_flow.async_register_implementation(
self.hass,
DOMAIN,
Expand All @@ -253,7 +263,6 @@ async def async_oauth_create_entry(self, data: dict) -> dict:
data[CONF_CLIENT_ID] = self.flow_impl.client_id
data[CONF_CLIENT_SECRET] = self.flow_impl.client_secret
data[CONF_PHOTOS] = self._import_photos_from_strava
data[CONF_DISTANCE_UNIT_OVERRIDE] = self._distance_unit_override_metric

return self.async_create_entry(title=CONFIG_ENTRY_TITLE, data=data)

Expand Down
164 changes: 101 additions & 63 deletions custom_components/ha_strava/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
UnitOfPower,
UnitOfSpeed,
)
from homeassistant.util.unit_conversion import DistanceConverter, SpeedConverter
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM

# custom module imports
Expand Down Expand Up @@ -65,7 +66,6 @@
DOMAIN,
EVENT_ACTIVITIES_UPDATE,
EVENT_SUMMARY_STATS_UPDATE,
FACTOR_KILOMETER_TO_MILE,
MAX_NB_ACTIVITIES,
UNIT_BEATS_PER_MINUTE,
UNIT_KILO_CALORIES,
Expand Down Expand Up @@ -119,10 +119,11 @@ async def async_setup_entry(
return


class StravaSummaryStatsSensor(SensorEntity): # pylint: disable=missing-class-docstring
_data = None # Strava activity data
class StravaSummaryStatsSensor(
SensorEntity
): # pylint: disable=missing-class-docstring,too-many-instance-attributes
_data = None
_activity_type = None

_attr_should_poll = False
_attr_state_class = SensorStateClass.TOTAL

Expand All @@ -131,10 +132,22 @@ def __init__(self, activity_type, metric, summary_type):
self._activity_type = activity_type
self._summary_type = summary_type
self.entity_id = f"{DOMAIN}.strava_stats_{self._summary_type}_{self._activity_type}_{self._metric}" # noqa: E501

self._attr_unique_id = (
f"strava_stats_{self._summary_type}_{self._activity_type}_{self._metric}"
)
config_entries = self.hass.config_entries.async_entries(domain=DOMAIN)
if len(config_entries) == 1:
conf_distance_unit_override = config_entries[0].options.get(
CONF_DISTANCE_UNIT_OVERRIDE, CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT
)
self._is_unit_metric_default = (
conf_distance_unit_override == CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT
)
self._is_unit_metric = (
conf_distance_unit_override == CONF_DISTANCE_UNIT_OVERRIDE_METRIC
)
else:
self._is_unit_metric_default = True

@property
def device_info(self):
Expand Down Expand Up @@ -165,7 +178,14 @@ def native_value(self):
return self._data[CONF_SENSOR_MOVING_TIME]

if self._metric == CONF_SENSOR_DISTANCE:
return f"{round(self._data[CONF_SENSOR_DISTANCE]/1000,2)}"
if self._is_unit_metric_default or self._is_unit_metric:
return f"{round(self._data[CONF_SENSOR_DISTANCE]/1000,2)}"

return DistanceConverter.convert(
(self._data[CONF_SENSOR_DISTANCE] / 1000),
UnitOfLength.KILOMETERS,
UnitOfLength.MILES,
)

return int(self._data[CONF_SENSOR_ACTIVITY_COUNT])

Expand All @@ -178,7 +198,9 @@ def native_unit_of_measurement(self):
return TIME_SECONDS

if self._metric == CONF_SENSOR_DISTANCE:
return UnitOfLength.KILOMETERS
if self._is_unit_metric_default or self._is_unit_metric:
return UnitOfLength.KILOMETERS
return UnitOfLength.MILES

return None

Expand All @@ -187,23 +209,9 @@ def suggested_unit_of_measurement(self):
if self._metric not in [CONF_SENSOR_DISTANCE]:
return super().suggested_unit_of_measurement

config_entries = self.hass.config_entries.async_entries(domain=DOMAIN)
if len(config_entries) != 1:
return super().suggested_unit_of_measurement

conf_distance_unit_override = config_entries[0].options.get(
CONF_DISTANCE_UNIT_OVERRIDE, CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT
)

if conf_distance_unit_override != CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT:
is_metric = (
conf_distance_unit_override == CONF_DISTANCE_UNIT_OVERRIDE_METRIC
)

if self._metric == CONF_SENSOR_DISTANCE:
return UnitOfLength.KILOMETERS if is_metric else UnitOfLength.MILES

return super().suggested_unit_of_measurement
if self._is_unit_metric_default or self._is_unit_metric:
return UnitOfLength.KILOMETERS
return UnitOfLength.MILES

@property
def name(self):
Expand Down Expand Up @@ -272,6 +280,19 @@ def __init__(self, activity_index, sensor_index):
self._activity_index = int(activity_index)
self.entity_id = f"{DOMAIN}.strava_{self._activity_index}_{self._sensor_index}"
self._attr_unique_id = f"strava_{self._activity_index}_{self._sensor_index}"
config_entries = self.hass.config_entries.async_entries(domain=DOMAIN)
if len(config_entries) == 1:
conf_distance_unit_override = config_entries[0].options.get(
CONF_DISTANCE_UNIT_OVERRIDE, CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT
)
self._is_unit_metric_default = (
conf_distance_unit_override == CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT
)
self._is_unit_metric = (
conf_distance_unit_override == CONF_DISTANCE_UNIT_OVERRIDE_METRIC
)
else:
self._is_unit_metric_default = True

@property
def device_info(self):
Expand Down Expand Up @@ -345,7 +366,12 @@ def native_value(self):
return self._data[CONF_SENSOR_ELAPSED_TIME]

if metric == CONF_SENSOR_DISTANCE:
return f"{round(self._data[CONF_SENSOR_DISTANCE]/1000,2)}"
distance = f"{round(self._data[CONF_SENSOR_DISTANCE]/1000,2)}"
if self._is_unit_metric_default or self._is_unit_metric:
return distance
return DistanceConverter.convert(
distance, UnitOfLength.KILOMETERS, UnitOfLength.MILES
)

if metric == CONF_SENSOR_PACE:
distance = self._data[CONF_SENSOR_DISTANCE]
Expand All @@ -356,30 +382,30 @@ def native_value(self):
/ (self._data[CONF_SENSOR_DISTANCE] / 1000)
)

pace_imperial = pace * FACTOR_KILOMETER_TO_MILE
pace_final = (
pace_imperial if self.hass.config.units is US_CUSTOMARY_SYSTEM else pace
pace_imperial = DistanceConverter.convert(
pace, UnitOfLength.KILOMETERS, UnitOfLength.MILES
)

config_entries = self.hass.config_entries.async_entries(domain=DOMAIN)
if len(config_entries) >= 1:
conf_distance_unit_override = config_entries[0].options.get(
CONF_DISTANCE_UNIT_OVERRIDE, CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT
if self._is_unit_metric_default:
pace_final = (
pace_imperial
if self.hass.config.units is US_CUSTOMARY_SYSTEM
else pace
)

if conf_distance_unit_override != CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT:
is_metric = (
conf_distance_unit_override
== CONF_DISTANCE_UNIT_OVERRIDE_METRIC
)
pace_final = pace if is_metric else pace_imperial
else:
pace_final = pace if self._is_unit_metric else pace_imperial

minutes = int(pace_final // 60)
seconds = int(pace_final - minutes * 60)
return "".join(["" if minutes == 0 else f"{minutes:02}:", f"{seconds:02}"])

if metric == CONF_SENSOR_SPEED:
return f"{round((self._data[CONF_SENSOR_DISTANCE]/1000) / (self._data[CONF_SENSOR_MOVING_TIME]/3600),2)}" # noqa: E501
speed = f"{round((self._data[CONF_SENSOR_DISTANCE]/1000) / (self._data[CONF_SENSOR_MOVING_TIME]/3600),2)}"
if self._is_unit_metric_default or self._is_unit_metric:
return speed
return SpeedConverter.convert(
speed, UnitOfSpeed.KILOMETERS_PER_HOUR, UnitOfSpeed.MILES_PER_HOUR
)

if metric == CONF_SENSOR_POWER:
return (
Expand All @@ -396,7 +422,12 @@ def native_value(self):
)

if metric == CONF_SENSOR_ELEVATION:
return f"{round(self._data[CONF_SENSOR_ELEVATION],0)}"
elevation_gain = f"{round(self._data[CONF_SENSOR_ELEVATION],0)}"
if self._is_unit_metric_default or self._is_unit_metric:
return elevation_gain
return DistanceConverter.convert(
elevation_gain, UnitOfLength.METERS, UnitOfLength.FEET
)

if metric == CONF_SENSOR_HEART_RATE_AVG:
return f"{round(self._data[CONF_SENSOR_HEART_RATE_AVG],1)}"
Expand All @@ -407,7 +438,9 @@ def native_value(self):
return str(self._data.get(metric))

@property
def native_unit_of_measurement(self): # pylint: disable=too-many-return-statements
def native_unit_of_measurement(
self,
): # pylint: disable=too-many-return-statements,too-many-branches
if not self._data or self._sensor_index == 0:
return None

Expand All @@ -420,22 +453,35 @@ def native_unit_of_measurement(self): # pylint: disable=too-many-return-stateme
return UnitOfPower.WATT

if metric == CONF_SENSOR_ELEVATION:
return UnitOfLength.METERS
if self._is_unit_metric_default or self._is_unit_metric:
return UnitOfLength.METERS
return UnitOfLength.FEET

if metric == CONF_SENSOR_SPEED:
return UnitOfSpeed.KILOMETERS_PER_HOUR
if self._is_unit_metric_default or self._is_unit_metric:
return UnitOfSpeed.KILOMETERS_PER_HOUR
return UnitOfSpeed.MILES_PER_HOUR

if metric == CONF_SENSOR_DISTANCE:
return UnitOfLength.KILOMETERS
if self._is_unit_metric_default or self._is_unit_metric:
return UnitOfLength.KILOMETERS
return UnitOfLength.MILES

if metric in [CONF_SENSOR_HEART_RATE_MAX, CONF_SENSOR_HEART_RATE_AVG]:
return UNIT_BEATS_PER_MINUTE

if metric == CONF_SENSOR_PACE:
if self._is_unit_metric_default:
return (
UNIT_PACE_MINUTES_PER_MILE
if self.hass.config.units is US_CUSTOMARY_SYSTEM
else UNIT_PACE_MINUTES_PER_KILOMETER
)

return (
UNIT_PACE_MINUTES_PER_MILE
if self.hass.config.units is US_CUSTOMARY_SYSTEM
else UNIT_PACE_MINUTES_PER_KILOMETER
UNIT_PACE_MINUTES_PER_KILOMETER
if self._is_unit_metric
else UNIT_PACE_MINUTES_PER_MILE
)

if metric == CONF_SENSOR_CALORIES:
Expand All @@ -459,36 +505,28 @@ def suggested_unit_of_measurement(
]:
return None

config_entries = self.hass.config_entries.async_entries(domain=DOMAIN)
if len(config_entries) != 1:
return None

conf_distance_unit_override = config_entries[0].options.get(
CONF_DISTANCE_UNIT_OVERRIDE, CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT
)

if conf_distance_unit_override == CONF_DISTANCE_UNIT_OVERRIDE_DEFAULT:
if self._is_unit_metric_default:
return None

is_metric = conf_distance_unit_override == CONF_DISTANCE_UNIT_OVERRIDE_METRIC

if metric == CONF_SENSOR_DISTANCE:
return UnitOfLength.KILOMETERS if is_metric else UnitOfLength.MILES
return (
UnitOfLength.KILOMETERS if self._is_unit_metric else UnitOfLength.MILES
)

if metric == CONF_SENSOR_SPEED:
return (
UnitOfSpeed.KILOMETERS_PER_HOUR
if is_metric
if self._is_unit_metric
else UnitOfSpeed.MILES_PER_HOUR
)

if metric == CONF_SENSOR_ELEVATION:
return UnitOfLength.METERS if is_metric else UnitOfLength.FEET
return UnitOfLength.METERS if self._is_unit_metric else UnitOfLength.FEET

if metric == CONF_SENSOR_PACE:
return (
UNIT_PACE_MINUTES_PER_KILOMETER
if is_metric
if self._is_unit_metric
else UNIT_PACE_MINUTES_PER_MILE
)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/ha_strava/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"nb_activities": "Number of concurrent Strava Activities",
"img_update_interval_seconds": "Image rotation (seconds)",
"conf_photos": "Import Photos from Strava?",
"conf_distance_unit": "Preferred distance unit system"
"conf_distance_unit": "Distance unit system to use"
}
}
},
Expand Down

0 comments on commit 6b30768

Please sign in to comment.