Skip to content

Commit

Permalink
reformatted with ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
rsnodgrass committed May 23, 2024
1 parent 1416d01 commit 28acdbe
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 140 deletions.
4 changes: 4 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# pre-commit autoupdate

fail_fast: true

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
Expand Down
76 changes: 38 additions & 38 deletions custom_components/poolmath/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,33 @@

LOG = logging.getLogger(__name__)

DEFAULT_POOL_ID = "unknown"
DEFAULT_POOL_ID = 'unknown'

KNOWN_SENSOR_KEYS = [
"fc",
"cc",
"cya",
"ch",
"ph",
"ta",
"salt",
"bor",
"tds",
"csi",
"waterTemp",
"flowRate",
"pressure",
"swgCellPercent",
'fc',
'cc',
'cya',
'ch',
'ph',
'ta',
'salt',
'bor',
'tds',
'csi',
'waterTemp',
'flowRate',
'pressure',
'swgCellPercent',
]

ONLY_INCLUDE_IF_TRACKED = {
"salt": "trackSalt",
"bor": "trackBor",
"cc": "trackCC",
"csi": "trackCSI",
'salt': 'trackSalt',
'bor': 'trackBor',
'cc': 'trackCC',
'csi': 'trackCSI',
}

EXAMPLE_URL = "https://api.poolmathapp.com/share/XXXXXX.json"
EXAMPLE_URL = 'https://api.poolmathapp.com/share/XXXXXX.json'


class PoolMathClient:
Expand All @@ -51,29 +51,29 @@ def __init__(self, url, name=DEFAULT_NAME, timeout=DEFAULT_TIMEOUT):

# parse out the unique pool identifier from the provided URL (include hyphen for tfp-)
self._pool_id = DEFAULT_POOL_ID
match = re.search(r"poolmathapp.com/(mypool|share)/([a-zA-Z0-9-]+)", self._url)
match = re.search(r'poolmathapp.com/(mypool|share)/([a-zA-Z0-9-]+)', self._url)
if match:
self._pool_id = match[2]
else:
LOG.error(f"Invalid URL for PoolMath {self._url}, use {EXAMPLE_URL} format")
LOG.error(f'Invalid URL for PoolMath {self._url}, use {EXAMPLE_URL} format')

self._json_url = f"https://api.poolmathapp.com/share/{self._pool_id}.json"
self._json_url = f'https://api.poolmathapp.com/share/{self._pool_id}.json'
if self._json_url != self._url:
LOG.warning(
f"Using JSON URL {self._json_url} instead of yaml configured URL {self._url}"
f'Using JSON URL {self._json_url} instead of yaml configured URL {self._url}'
)

async def async_update(self):
"""Fetch latest json formatted data from the Pool Math API"""

async with httpx.AsyncClient() as client:
LOG.info(
f"GET {self._json_url} (timeout={self._timeout}; name={self.name}; id={self.pool_id})"
f'GET {self._json_url} (timeout={self._timeout}; name={self.name}; id={self.pool_id})'
)
response = await client.request(
"GET", self._json_url, timeout=self._timeout, follow_redirects=True
'GET', self._json_url, timeout=self._timeout, follow_redirects=True
)
LOG.debug(f"GET {self._json_url} response: {response.status_code}")
LOG.debug(f'GET {self._json_url} response: {response.status_code}')

if response.status_code == httpx.codes.OK:
return json.loads(response.text)
Expand All @@ -87,12 +87,12 @@ async def process_log_entry_callbacks(self, poolmath_json, async_callback):
if not poolmath_json:
return

pools = poolmath_json.get("pools")
pools = poolmath_json.get('pools')
if not pools:
return

pool = pools[0].get("pool")
overview = pool.get("overview")
pool = pools[0].get('pool')
overview = pool.get('overview')

latest_timestamp = None
for measurement in KNOWN_SENSOR_KEYS:
Expand All @@ -105,30 +105,30 @@ async def process_log_entry_callbacks(self, poolmath_json, async_callback):
if measurement in ONLY_INCLUDE_IF_TRACKED:
if not pool.get(ONLY_INCLUDE_IF_TRACKED.get(measurement)):
LOG.info(
f"Ignoring measurement {measurement} since tracking is disable in PoolMath"
f'Ignoring measurement {measurement} since tracking is disable in PoolMath'
)
continue

timestamp = overview.get(f"{measurement}Ts")
timestamp = overview.get(f'{measurement}Ts')

# find the timestamp of the most recent measurement update
if not latest_timestamp or timestamp > latest_timestamp:
latest_timestamp = timestamp

# add any attributes relevent to this measurement
attributes = {}
value_min = pool.get(f"{measurement}Min")
value_min = pool.get(f'{measurement}Min')
if value_min:
attributes[ATTR_TARGET_MIN] = value_min

value_max = pool.get(f"{measurement}Max")
value_max = pool.get(f'{measurement}Max')
if value_max:
attributes[ATTR_TARGET_MAX] = value_max

target = pool.get(f"{measurement}Target")
target = pool.get(f'{measurement}Target')
if target:
attributes["target"] = target
attributes[ATTR_TARGET_SOURCE] = "PoolMath"
attributes['target'] = target
attributes[ATTR_TARGET_SOURCE] = 'PoolMath'

# update the sensor
await async_callback(
Expand All @@ -151,4 +151,4 @@ def url(self):

@staticmethod
def _entry_timestamp(entry):
return entry.find("time", class_="timestamp timereal").text
return entry.find('time', class_='timestamp timereal').text
26 changes: 13 additions & 13 deletions custom_components/poolmath/const.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
"""Constants for Pool Math."""

DOMAIN = "poolmath"
DOMAIN = 'poolmath'

ATTRIBUTION = "Data by PoolMath (Trouble Free Pool)"
ATTRIBUTION = 'Data by PoolMath (Trouble Free Pool)'

ATTR_ATTRIBUTION = "attribution"
ATTR_DESCRIPTION = "description"
ATTR_LAST_UPDATED_TIME = "last_updated"
ATTR_TARGET_MIN = "target_min"
ATTR_TARGET_MAX = "target_max"
ATTR_TARGET_SOURCE = "target_source"
ATTR_ATTRIBUTION = 'attribution'
ATTR_DESCRIPTION = 'description'
ATTR_LAST_UPDATED_TIME = 'last_updated'
ATTR_TARGET_MIN = 'target_min'
ATTR_TARGET_MAX = 'target_max'
ATTR_TARGET_SOURCE = 'target_source'

CONF_TARGET = "target"
CONF_TIMEOUT = "timeout"
CONF_TARGET = 'target'
CONF_TIMEOUT = 'timeout'

DEFAULT_NAME = "Pool"
DEFAULT_NAME = 'Pool'
DEFAULT_TIMEOUT = 15.0

ICON_GAUGE = "mdi:gauge"
ICON_POOL = "mdi:pool"
ICON_GAUGE = 'mdi:gauge'
ICON_POOL = 'mdi:pool'
47 changes: 25 additions & 22 deletions custom_components/poolmath/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
ATTR_UNIT_OF_MEASUREMENT,
CONF_NAME,
CONF_URL,
UnitOfTemperature
UnitOfTemperature,
)

from homeassistant.core import callback
Expand All @@ -36,7 +36,7 @@

LOG = logging.getLogger(__name__)

DATA_UPDATED = "poolmath_data_updated"
DATA_UPDATED = 'poolmath_data_updated'

SCAN_INTERVAL = timedelta(minutes=15)

Expand All @@ -47,8 +47,8 @@
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
# NOTE: targets are not really implemented, other than tfp
vol.Optional(
CONF_TARGET, default="tfp"
): cv.string # targets/*.yaml file with min/max targets
CONF_TARGET, default='tfp'
): cv.string, # targets/*.yaml file with min/max targets
# FIXME: allow specifying EXACTLY which log types to monitor, always create the sensors
# vol.Optional(CONF_LOG_TYPES, default=None):
}
Expand Down Expand Up @@ -96,7 +96,7 @@ def __init__(
@property
def name(self):
"""Return the name of the sensor."""
return "Pool Math Service: " + self._name
return 'Pool Math Service: ' + self._name

@property
def state(self):
Expand All @@ -119,21 +119,21 @@ async def async_update(self):
client = self._poolmath_client
poolmath_json = await client.async_update()
except Exception as e:
LOG.warning(f"PoolMath request failed! {url}: {e}")
LOG.warning(f'PoolMath request failed! {url}: {e}')
return

if not poolmath_json:
LOG.warning(f"PoolMath returned NO JSON data: {url}")
LOG.warning(f'PoolMath returned NO JSON data: {url}')
return

# update state attributes with relevant data
pools = poolmath_json.get("pools")
pools = poolmath_json.get('pools')
if not pools:
LOG.warning(f"PoolMath returned EMPTY pool data: {url}")
LOG.warning(f'PoolMath returned EMPTY pool data: {url}')
return

pool = pools[0].get("pool")
self._attrs |= {"name": pool.get("name"), "volume": pool.get("volume")}
pool = pools[0].get('pool')
self._attrs |= {'name': pool.get('name'), 'volume': pool.get('volume')}

# iterate through all the log entries and update sensor states
timestamp = await client.process_log_entry_callbacks(
Expand All @@ -156,7 +156,7 @@ async def get_sensor_entity(self, sensor_type, poolmath_json):
LOG.warning(f"Unknown sensor '{sensor_type}' discovered for {self.name}")
return None

name = self._name + " " + config[ATTR_NAME]
name = self._name + ' ' + config[ATTR_NAME]
pool_id = self._poolmath_client.pool_id

sensor = UpdatableSensor(
Expand All @@ -176,7 +176,7 @@ async def _update_sensor_callback(
sensor = await self.get_sensor_entity(measurement_type, poolmath_json)
if sensor and sensor.state != state:
LOG.info(
f"{sensor.name} {measurement_type}={state} {sensor.unit_of_measurement} (timestamp={timestamp})"
f'{sensor.name} {measurement_type}={state} {sensor.unit_of_measurement} (timestamp={timestamp})'
)
sensor.inject_state(state, timestamp, attributes)

Expand All @@ -200,7 +200,7 @@ def __init__(self, hass, pool_id, name, config, sensor_type, poolmath_json):
self._state = None

if pool_id:
self._unique_id = f"poolmath_{pool_id}_{sensor_type}"
self._unique_id = f'poolmath_{pool_id}_{sensor_type}'
else:
self._unique_id = None

Expand All @@ -210,26 +210,29 @@ def __init__(self, hass, pool_id, name, config, sensor_type, poolmath_json):
# applies to other units). No time to fix now, but perhaps someone will submit a PR
# to fix this in future.
self._unit_of_measurement = self._config[ATTR_UNIT_OF_MEASUREMENT]
if self._unit_of_measurement in [UnitOfTemperature.FAHRENHEIT, UnitOfTemperature.CELSIUS]:
if self._unit_of_measurement in [
UnitOfTemperature.FAHRENHEIT,
UnitOfTemperature.CELSIUS,
]:
# inspect the first JSON response to determine things that are not specified
# with sensor values (since units/update timestamps are in separate keys
# within the JSON doc)
pools = poolmath_json.get("pools")
pools = poolmath_json.get('pools')
if pools:
pool = pools[0].get("pool")
if pool.get("waterTempUnitDefault") == 1:
pool = pools[0].get('pool')
if pool.get('waterTempUnitDefault') == 1:
self._unit_of_measurement = UnitOfTemperature.CELSIUS
else:
self._unit_of_measurement = UnitOfTemperature.FAHRENHEIT

LOG.info(f"Unit of temperature measurement {self._unit_of_measurement}")
LOG.info(f'Unit of temperature measurement {self._unit_of_measurement}')

# FIXME: use 'targets' configuration value and load appropriate yaml
targets_map = get_pool_targets()
if targets_map:
self._targets = targets_map.get(sensor_type)
if self._targets:
self._attrs[ATTR_TARGET_SOURCE] = "tfp"
self._attrs[ATTR_TARGET_SOURCE] = 'tfp'
self._attrs.update(self._targets)

@property
Expand Down Expand Up @@ -262,7 +265,7 @@ def extra_state_attributes(self):

@property
def icon(self):
return self._config["icon"]
return self._config['icon']

def inject_state(self, state, timestamp, attributes):
state_changed = self._state != state
Expand Down Expand Up @@ -294,7 +297,7 @@ async def async_added_to_hass(self) -> None:
if not state:
return
self._state = state.state
LOG.debug(f"Restored sensor {self._name} previous state {self._state}")
LOG.debug(f'Restored sensor {self._name} previous state {self._state}')

# restore attributes
if ATTR_LAST_UPDATED_TIME in state.attributes:
Expand Down
Loading

0 comments on commit 28acdbe

Please sign in to comment.