Skip to content

Commit

Permalink
extra sensor to make it easier to build conditions/automations/notifi…
Browse files Browse the repository at this point in the history
…cations for warnings for any item of any user at any library within the account.

Examples added in readme
  • Loading branch information
myTselection committed Jan 30, 2023
1 parent d4d37d4 commit 1b64046
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 2 deletions.
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- Sensor `Bibliotheek.be` should become available with the number of items lent out.
- sensor.bibliotheek_be_`<username>`_`<library>` will be created for each user linked to the account
- sensor.bibliotheek_be_bib_`<library>` will be created for each library
- sensor.bibliotheek_be_warning will indicate if within how many days some items have to be returned at *any* library (this can be used of conditions, notifications, etc).

## Status
Still some optimisations are planned, see [Issues](https://github.com/myTselection/bibliotheek_be/issues) section in GitHub.
Expand Down Expand Up @@ -157,3 +158,46 @@ content: >-
{% endfor %}
title: Gebruikers
```

### Example with conditional check for warnings:

## Extra binary sensor based on personal perference on number of days to limit the warning
Example provided with sensor that will turn on if items have to be returned within 7 days. The alert sensor will be turned on if items have to be returned within 7 days and no extension is possible.
`configuration.yaml`:
```
binary_sensor:
- platform: template
sensors:
bibliotheek_warning_7d:
friendly_name: Bibliotheek Warning 7d
value_template: >
{{states('sensor.bibliotheek_be_warning')|int <= 7}}
- platform: template
sensors:
bibliotheek_alert_7d:
friendly_name: Bibliotheek Alert 7d
value_template: >
{{states('sensor.bibliotheek_be_warning')|int <= 7 and state_attr('sensor.bibliotheek_be_warning','some_not_extendable') == True}}
```
Base on these sensors, a automation can be build for notifications or below conditional card can be defined:

```
- type: conditional
conditions:
- entity: binary_sensor.bibliotheek_warning_7d
state: 'on'
- entity: binary_sensor.bibliotheek_alert_7d
state: 'off'
card:
type: markdown
content: ⏰Boeken verlengen deze week !
- type: conditional
conditions:
- entity: binary_sensor.bibliotheek_warning_7d
state: 'on'
- entity: binary_sensor.bibliotheek_alert_7d
state: 'on'
card:
type: markdown
content: ⏰Boeken binnen brengen deze week !
```
2 changes: 1 addition & 1 deletion custom_components/bibliotheek_be/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"iot_class": "cloud_polling",
"name": "Bibliotheek.be",
"requirements": ["bs4", "html5lib"],
"version": "0.4.0",
"version": "0.5.0",
"integration_type": "hub",
"issue_tracker": "https://github.com/myTselection/bibliotheek_be/issues"
}
120 changes: 119 additions & 1 deletion custom_components/bibliotheek_be/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ async def dry_setup(hass, config_entry, async_add_devices):
_LOGGER.debug(f"{NAME} Init sensor for date {libraryName}")
sensors.append(sensorDate)

sensorLibrariesWarning = ComponentLibrariesWarningSensor(componentData, hass)
sensors.append(sensorLibrariesWarning)

async_add_devices(sensors)

#TODO: sensor per library (total items loand from library), attribute: number of each type lended
Expand Down Expand Up @@ -265,6 +268,7 @@ def __init__(self, data, hass, libraryName, loanTypes):
self._last_update = None
self._lowest_till_date = None
self._days_left = None
self._some_not_extendable = False
self._loandetails = []
self._num_loans = 0
self._num_total_loans = 0
Expand All @@ -283,6 +287,7 @@ async def async_update(self):
self._loantypes= {key: 0 for key in self._loantypes}
self._num_loans = 0
self._num_total_loans = 0
self._some_not_extendable = False

for user_id, loan_data in self._data._loandetails.items():
_LOGGER.debug(f"library loop {user_id} {self._libraryName}")
Expand All @@ -298,9 +303,13 @@ async def async_update(self):
self._days_left = loan_item.get('days_remaining')
self._lowest_till_date = loan_item.get('loan_till')
self._num_loans = 1
if loan_item.get('extend_loan_id') == '':
self._some_not_extendable = True
if self._days_left == loan_item.get('days_remaining'):
_LOGGER.debug(f"library_name_loop same days {library_name_loop} {loan_item}")
self._num_loans += 1
if loan_item.get('extend_loan_id') == '':
self._some_not_extendable = True


async def async_will_remove_from_hass(self):
Expand Down Expand Up @@ -333,6 +342,7 @@ def extra_state_attributes(self) -> dict:
"last update": self._last_update,
"libraryName": self._libraryName,
"days_left": self._days_left,
"some_not_extendable": self._some_not_extendable,
"lowest_till_date": self._lowest_till_date,
"num_loans": self._num_loans,
"num_total_loans": self._num_total_loans,
Expand All @@ -341,7 +351,115 @@ def extra_state_attributes(self) -> dict:
}
attributes.update(self._loantypes)
return attributes
_num_total_loans

@property
def device_info(self) -> dict:
"""I can't remember why this was needed :D"""
return {
"identifiers": {(DOMAIN, self.unique_id)},
"name": self.name,
"manufacturer": DOMAIN,
}

@property
def unit(self) -> int:
"""Unit"""
return int

@property
def unit_of_measurement(self) -> str:
"""Return the unit of measurement this sensor expresses itself in."""
return "days"

@property
def friendly_name(self) -> str:
return self.name


class ComponentLibrariesWarningSensor(Entity):
def __init__(self, data, hass):
self._data = data
self._hass = hass
self._last_update = None
self._lowest_till_date = None
self._days_left = None
self._some_not_extendable = False
self._num_loans = 0
self._num_total_loans = 0
self._library_name = ""

@property
def state(self):
"""Return the state of the sensor."""
return self._days_left

async def async_update(self):
await self._data.update()
self._last_update = self._data._lastupdate;
self._num_loans = 0
self._num_total_loans = 0
self._some_not_extendable = False
self._library_name = ""

for user_id, loan_data in self._data._loandetails.items():
_LOGGER.debug(f"library warning loop {user_id}")
for loan_id, loan_item in loan_data.items():
library_name_loop = loan_item.get('library')
_LOGGER.debug(f"library_name_loop {library_name_loop}")
self._num_total_loans += 1
if loan_item.get('days_remaining') and ((self._days_left is None) or (self._days_left > loan_item.get('days_remaining'))):
_LOGGER.debug(f"library_name_loop less days {library_name_loop} {loan_item}")
self._days_left = loan_item.get('days_remaining')
self._lowest_till_date = loan_item.get('loan_till')
self._num_loans = 1
self._library_name = f"{loan_item.get('library')}"
if loan_item.get('extend_loan_id') == '':
self._some_not_extendable = True
if self._days_left == loan_item.get('days_remaining'):
_LOGGER.debug(f"library_name_loop same days {library_name_loop} {loan_item}")
self._num_loans += 1
if loan_item.get('library') and loan_item.get('library') not in self._library_name:
self._library_name += f", {loan_item.get('library')}"
if loan_item.get('extend_loan_id') == '':
self._some_not_extendable = True


async def async_will_remove_from_hass(self):
"""Clean up after entity before removal."""
_LOGGER.info("async_will_remove_from_hass " + NAME)
self._data.clear_session()


@property
def icon(self) -> str:
"""Shows the correct icon for container."""
return "mdi:bookshelf"

@property
def unique_id(self) -> str:
"""Return the name of the sensor."""
return (
f"{NAME} warning"
)

@property
def name(self) -> str:
return self.unique_id

@property
def extra_state_attributes(self) -> dict:
"""Return the state attributes."""
attributes = {
ATTR_ATTRIBUTION: NAME,
"last update": self._last_update,
"days_left": self._days_left,
"some_not_extendable": self._some_not_extendable,
"lowest_till_date": self._lowest_till_date,
"num_loans": self._num_loans,
"num_total_loans": self._num_total_loans,
"library_name": self._library_name
}
return attributes

@property
def device_info(self) -> dict:
Expand Down

0 comments on commit 1b64046

Please sign in to comment.