Skip to content

Commit

Permalink
Add user defined static data
Browse files Browse the repository at this point in the history
  • Loading branch information
rgc99 committed Oct 24, 2023
1 parent e410b96 commit b8ee0a2
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions custom_components/irrigation_unlimited/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
CONF_PRECISION = "precision"
CONF_QUEUE = "queue"
CONF_QUEUE_MANUAL = "queue_manual"
CONF_USER = "user"

# Defaults
DEFAULT_NAME = DOMAIN
Expand Down
33 changes: 33 additions & 0 deletions custom_components/irrigation_unlimited/irrigation_unlimited.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
CONF_PRECISION,
CONF_QUEUE,
CONF_QUEUE_MANUAL,
CONF_USER,
)

_LOGGER: Logger = getLogger(__package__)
Expand Down Expand Up @@ -499,6 +500,24 @@ def to_dict(self) -> dict:
return result


class IUUser(dict):
"""Class to hold arbitrary static user information"""

def load(self, config: OrderedDict, all_zones: OrderedDict):
"""Load info data from the configuration"""

def load_params(config: OrderedDict) -> None:
if config is None:
return
for key, data in config.items():
self[f"{CONF_USER}_{key}"] = data

self.clear()
if all_zones is not None:
load_params(all_zones.get(CONF_USER))
load_params(config.get(CONF_USER))


class IUSchedule(IUBase):
"""Irrigation Unlimited Schedule class. Schedules are not actual
points in time but describe a future event i.e. next Monday at
Expand Down Expand Up @@ -1609,6 +1628,7 @@ def __init__(
self._dirty: bool = True
self._switch = IUSwitch(hass, coordinator, controller, self)
self._volume = IUVolume(hass, coordinator)
self._user = IUUser()

@property
def unique_id(self) -> str:
Expand Down Expand Up @@ -1752,6 +1772,11 @@ def configuration(self) -> str:
"""Return this zone as JSON"""
return json.dumps(self.as_dict(), cls=IUJSONEncoder)

@property
def user(self) -> dict:
"""Return the arbitrary user information"""
return self._user

def _is_setup(self) -> bool:
"""Check if this object is setup"""
self._initialised = self._zone_sensor is not None
Expand Down Expand Up @@ -1890,6 +1915,7 @@ def load(self, config: OrderedDict, all_zones: OrderedDict) -> "IUZone":
self.find_add(sidx).load(schedule_config)
self._switch.load(config, all_zones)
self._volume.load(config, all_zones)
self._user.load(config, all_zones)
self._dirty = True
return self

Expand Down Expand Up @@ -3077,6 +3103,7 @@ def __init__(
self._sensor_update_required: bool = False
self._sensor_last_update: datetime = None
self._suspend_until: datetime = None
self._user = IUUser()
self._dirty: bool = True

@property
Expand Down Expand Up @@ -3205,6 +3232,11 @@ def icon(self) -> str:
return ICON_SUSPENDED
return ICON_DISABLED

@property
def user(self) -> dict:
"""Return the arbitrary user information"""
return self._user

def _status(self) -> str:
"""Return status of the controller"""
if self._initialised:
Expand Down Expand Up @@ -3317,6 +3349,7 @@ def load(self, config: OrderedDict) -> "IUController":
self._sequences.clear()

self._switch.load(config, None)
self._user.load(config, None)
self._dirty = True
return self

Expand Down
9 changes: 9 additions & 0 deletions custom_components/irrigation_unlimited/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
CONF_PRECISION,
CONF_QUEUE,
CONF_QUEUE_MANUAL,
CONF_USER,
)

IU_ID = r"^[a-z0-9]+(_[a-z0-9]+)*$"
Expand All @@ -103,6 +104,11 @@ def _parse_dd_mmm(value: str) -> date | None:
return datetime.strptime(value, "%d %b").date()


USER_SCHEMA = vol.Schema(
{},
extra=vol.ALLOW_EXTRA,
)

SHOW_SCHEMA = vol.Schema(
{
vol.Optional(CONF_CONFIG, False): cv.boolean,
Expand Down Expand Up @@ -222,6 +228,7 @@ def _parse_dd_mmm(value: str) -> date | None:
vol.Optional(CONF_CHECK_BACK): vol.All(CHECK_BACK_SCHEMA),
vol.Optional(CONF_VOLUME): vol.All(VOLUME_SCHEMA),
vol.Optional(CONF_DURATION): cv.positive_time_period_template,
vol.Optional(CONF_USER): vol.All(USER_SCHEMA),
}
)

Expand All @@ -235,6 +242,7 @@ def _parse_dd_mmm(value: str) -> date | None:
vol.Optional(CONF_CHECK_BACK): vol.All(CHECK_BACK_SCHEMA),
vol.Optional(CONF_VOLUME): vol.All(VOLUME_SCHEMA),
vol.Optional(CONF_DURATION): cv.positive_time_period_template,
vol.Optional(CONF_USER): vol.All(USER_SCHEMA),
}
)

Expand Down Expand Up @@ -281,6 +289,7 @@ def _parse_dd_mmm(value: str) -> date | None:
vol.Optional(CONF_ALL_ZONES_CONFIG): vol.All(ALL_ZONES_SCHEMA),
vol.Optional(CONF_QUEUE_MANUAL): cv.boolean,
vol.Optional(CONF_CHECK_BACK): vol.All(CHECK_BACK_SCHEMA),
vol.Optional(CONF_USER): vol.All(USER_SCHEMA),
}
)

Expand Down
49 changes: 49 additions & 0 deletions tests/configs/test_user.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
default_config:

irrigation_unlimited:
refresh_interval: 2000
testing:
enabled: true
speed: 1.0
output_events: false
show_log: false
autoplay: false
times:
- name: "1-Sequence 1"
start: "2023-10-24 06:00"
end: "2023-10-24 07:00"
results:
- {t: '2023-10-24 06:05', c: 1, z: 0, s: 1}
- {t: '2023-10-24 06:05', c: 1, z: 1, s: 1}
- {t: '2023-10-24 06:11', c: 1, z: 1, s: 0}
- {t: '2023-10-24 06:11', c: 1, z: 0, s: 0}
- {t: '2023-10-24 06:12', c: 1, z: 0, s: 1}
- {t: '2023-10-24 06:12', c: 1, z: 2, s: 1}
- {t: '2023-10-24 06:24', c: 1, z: 2, s: 0}
- {t: '2023-10-24 06:24', c: 1, z: 0, s: 0}
controllers:
- name: "Test controller 1"
user:
area: My Farm
picture: /my_pic.jpg
all_zones_config:
user:
actuator: KNX 6.1
zones:
- name: "Zone 1"
user:
area: Eastern Pastures
flow_rate_gallon_per_minute: 25
picture: /my_pic.jpg
gps: 42.746635,-75.770045
- name: "Zone 2"
sequences:
- name: "Sequence 1"
delay: "0:01:00"
schedules:
- time: "06:05"
zones:
- zone_id: 1
duration: "0:06:00"
- zone_id: 2
duration: "0:12:00"
26 changes: 26 additions & 0 deletions tests/test_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""irrigation_unlimited user data test"""
import homeassistant.core as ha
from tests.iu_test_support import IUExam

IUExam.quiet_mode()


async def test_user(hass: ha.HomeAssistant, skip_dependencies, skip_history):
"""Test IUUser class."""
# pylint: disable=unused-argument

# Start an examination
async with IUExam(hass, "test_user.yaml") as exam:
await exam.begin_test(1)
attr = hass.states.get("binary_sensor.irrigation_unlimited_c1_m").attributes
assert attr["user_area"] == "My Farm"
assert attr["user_picture"] == "/my_pic.jpg"
attr = hass.states.get("binary_sensor.irrigation_unlimited_c1_z1").attributes
assert attr["user_area"] == "Eastern Pastures"
assert attr["user_actuator"] == "KNX 6.1"
assert attr["user_flow_rate_gallon_per_minute"] == 25
assert attr["user_picture"] == "/my_pic.jpg"
assert attr["user_gps"] == "42.746635,-75.770045"
await exam.finish_test()

exam.check_summary()

0 comments on commit b8ee0a2

Please sign in to comment.