Skip to content

Commit

Permalink
Merge pull request #67 from virtualdj/new-ver-1
Browse files Browse the repository at this point in the history
Nuova API sito GME e riscrittura generale
  • Loading branch information
virtualdj authored Nov 14, 2024
2 parents fd7bdce + fb11c94 commit bc759c6
Show file tree
Hide file tree
Showing 21 changed files with 966 additions and 687 deletions.
27 changes: 12 additions & 15 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
"PYTHONASYNCIODEBUG": "1"
},
"runArgs": ["-e", "GIT_EDITOR=code --wait"],
"forwardPorts": [
8123
],
"forwardPorts": [8123],
"portsAttributes": {
"8123": {
"label": "Home Assistant",
"onAutoForward": "notify"
}
"8123": {
"label": "Home Assistant",
"onAutoForward": "notify"
}
},
"customizations": {
"vscode": {
Expand All @@ -25,8 +23,9 @@
"ms-python.vscode-pylance",
"redhat.vscode-yaml",
"esbenp.prettier-vscode",
"ryanluker.vscode-coverage-gutters",
"thibault-vanderseypen.i18n-json-editor"
"thibault-vanderseypen.i18n-json-editor",
"eamodio.gitlens",
"ms-python.mypy-type-checker"
],
"settings": {
"files.eol": "\n",
Expand All @@ -39,6 +38,7 @@
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true
},
"python.linting.mypyArgs": ["--cache-dir=.mypy_cache"],
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
Expand All @@ -47,16 +47,13 @@
"files.trimTrailingWhitespace": false
},
"i18nJsonEditor.forceKeyUPPERCASE": false,
"i18nJsonEditor.supportedFolders": [
"translations",
"i18n"
]
"i18nJsonEditor.supportedFolders": ["translations", "i18n"]
}
}
},
"remoteUser": "vscode",
"features": {
"ghcr.io/devcontainers/features/rust:1": {}
//"ghcr.io/devcontainers-contrib/features/ffmpeg-apt-get:1": {}
"ghcr.io/devcontainers/features/rust:1": {}
//"ghcr.io/devcontainers-contrib/features/ffmpeg-apt-get:1": {}
}
}
12 changes: 12 additions & 0 deletions .devcontainer/scripts/clear-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

set -e

cd "$(dirname "$0")/../.."

# Termina Home Assistant se in esecuzione
if pgrep hass; then pkill hass; fi

# Elimina i file nella cartella 'config' (escluso il file 'configuration.yaml')
find config -mindepth 1 ! -name 'configuration.yaml' -exec rm -rf {} +
echo "Configuration cleared."
8 changes: 8 additions & 0 deletions .devcontainer/scripts/type-check
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

set -e

cd "$(dirname "$0")/../.."

echo "Be patient, may take several minutes..."
mypy --cache-dir=.mypy_cache custom_components/pun_sensor
2 changes: 1 addition & 1 deletion .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ categories:
- 'bug'

- title: '🧰 Manutenzione'
label:
labels:
- 'dependencies'
- 'documentation'
- 'maintenance'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release-drafter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- master


jobs:
update_release_draft:
name: Update release draft
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Release

on:
release:
# types: [prereleased,published]
# types: [prereleased,published]
types: [published]

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,4 @@ dmypy.json

# Home Assistant Config
/config/*
!/config/configuration.yaml
!/config/configuration.yaml
12 changes: 12 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"command": "pkill hass ; .devcontainer/scripts/develop",
"problemMatcher": []
},
{
"label": "Clear Home Assistant config",
"type": "shell",
"command": ".devcontainer/scripts/clear-config",
"problemMatcher": []
},
{
"label": "Upgrade Home Assistant to latest (beta)",
"type": "shell",
Expand All @@ -42,6 +48,12 @@
"type": "shell",
"command": ".devcontainer/scripts/lint",
"problemMatcher": []
},
{
"label": "Type-check with mypy",
"type": "shell",
"command": ".devcontainer/scripts/type-check",
"problemMatcher": []
}
]
}
26 changes: 26 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Note di sviluppo

Questa è la mia prima esperienza con le integrazioni di Home Assistant e, in generale, con Python. Purtroppo, mio malgrado, ho scoperto che la **documentazione di Home Assistant** per quanto riguarda la creazione di nuove integrazioni è **scarsa e incompleta**.

Nella prima versione (commit [d239dae](https://github.com/virtualdj/pun_sensor/commit/d239dae713ae2d06e0e80f8625eab84dc3bb4e02)) ho provato ad effettuare un polling ogni 10 secondi sia per verificare se è sopraggiunto l'orario di aggiornamento dei prezzi che per calcolare la fascia oraria corrente. Ma, specie per il calcolo della fascia, non era il metodo corretto perché non è detto che l'aggiornamento avvenisse al secondo 0 della nuova fascia.
Così, cercando altri sorgenti in giro su GitHub, ho scoperto che esiste una funzione in Home Assistant chiamata `async_track_point_in_time` che consente di schedulare l'esecuzione di una routine in un determinato istante nel tempo, che viene rispettato perfettamente. La versione successiva è stata quindi riscritta utilizzando questo metodo (più efficiente).

Ovviamente non ho alcuna certezza che tutto questo sia la maniera giusta di procedere, ma funziona! Per chi di interesse, questi sono i progetti da cui ho tratto del codice interessante da utilizzare per il mio:

- [zaubererty/homeassistant-mvpv](https://github.com/zaubererty/homeassistant-mvpv/blob/d124543a36ab90b94b85a2211f41fee5943239ac/custom_components/mypv/coordinator.py)
- [Gradecak/spaarnelanden-containers](https://github.com/Gradecak/spaarnelanden-containers/blob/39db00072bdd4f99d1cf543fba314d161147259c/custom_components/spaarnelanden/sensor.py)
- [nintendo_wishlist](https://github.com/custom-components/sensor.nintendo_wishlist/tree/main/custom_components/nintendo_wishlist)
- [saso5/homeassistant-mojelektro](https://github.com/saso5/homeassistant-mojelektro/tree/d747e74a842be5697494da6403a1055fcb4322bf/custom_components/mojelektro)
- [YodaDaCoda/hass-solarman-modbus](https://github.com/YodaDaCoda/hass-solarman-modbus/blob/36ebd2d7eef7834867805ae01de433e8f8ab2ddb/custom_components/solarman/config_flow.py)
- [bruxy70/Garbage-Collection](https://github.com/bruxy70/Garbage-Collection/blob/ae73818b3b0786ebcf72b16a6f27428e516686e6/custom_components/garbage_collection/sensor.py)
- [dcmeglio/alarmdecoder-hass](https://github.com/dcmeglio/alarmdecoder-hass/blob/a898ae18cc5562b2a5fc3a73511302b6d242fd07/custom_components/alarmdecoder/__init__.py)
- [BenPru/luxtronik](https://github.com/BenPru/luxtronik/blob/a6c5adfe91532237075fe17df63b59120a8b7098/custom_components/luxtronik/sensor.py#L856-L857) e [collse/Home-AssistantConfig](https://github.com/collse/Home-AssistantConfig/blob/e4a1bc6ee3c470619e4169ac903b88f5dad3b6a8/custom_components/elastic/sensor.py#L66) per due esempi di come assegnare un _entity-id_ predeterminato quando si usa anche l'_unique_id_ senza ricevere errori `AttributeError: can't set attribute 'entity_id'` (altra cosa non sufficientemente documentata di HomeAssistant)
- [dlashua/bolted](https://github.com/dlashua/bolted/blob/50065eba8ffb4abe498587cd889aa9ff7873aeb3/custom_components/bolted/entity_manager.py), [pippyn/Home-Assistant-Sensor-Afvalbeheer](https://github.com/pippyn/Home-Assistant-Sensor-Afvalbeheer/blob/master/custom_components/afvalbeheer/sensor.py) e [questo articolo](https://aarongodfrey.dev/programming/restoring-an-entity-in-home-assistant/) per come salvare e ripristinare lo stato di una entità con `RestoreEntity`
- Il componente di Home Assistant [energyzero](https://github.com/home-assistant/core/tree/dev/homeassistant/components/energyzero) per il blocco del `config_flow` già configurato e per esprimere correttamente le unità di misura
- La [PR #99213](https://github.com/home-assistant/core/pull/99213/files) di Home Assistant per il suggerimento di usare `async_call_later` anziché sommare il timedelta all'ora corrente
- La [PR #76793](https://github.com/home-assistant/core/pull/76793/files) di Home Assistant per un esempio di come usare il [cancellation token](https://developers.home-assistant.io/docs/integration_listen_events/#available-event-helpers) restituito da `async_track_point_in_time`
- I commit [1](https://github.com/home-assistant/core/commit/c574d86ddbafd6c18995ad9efb297fda3ce4292c) e [2](https://github.com/home-assistant/core/commit/36e7689d139d0f517bbdd8f8f2c11e18936d27b3) per risolvere il warning nei log `[homeassistant.util.loop] Detected blocking call to import_module inside the event loop by custom integration` comparso con la versione 2024.5.0 di Home Assistant e dovuto alle librerie importate
- La configurazione del _devcontainer_ con script ispirati dalla repository [astrandb/viva](https://github.com/astrandb/viva/tree/main/scripts) e da post sulla [community Home Assistant](https://community.home-assistant.io/t/developing-home-assistant-core-in-a-vscode-devcontainer/235650/36); utili anche [questo](https://www.hacf.fr/dev_tuto_1_environnement/) e [questo](https://svrooij.io/2023/01/18/home-assistant-component/)
- [Questa parte](https://github.com/bdraco/home-assistant/blob/4224234b7abfd1b31f75637b910f4fb89d5b4a0d/homeassistant/components/workday/__init__.py#L27-L31) di codice per effettuare il precaricamento corretto del modulo _holidays_ con `async_add_import_executor_job` senza che desse errori nel lint (si vede bene in [questa commit](https://github.com/virtualdj/pun_sensor/commit/17141bd3dd2914e6dab27c4fbe6a07c2274c29e4))... Ma come si poteva capire?
- La [documentazione](https://developers.home-assistant.io/docs/config_entries_config_flow_handler#config-entry-migration) e [questo esempio](https://github.com/home-assistant/core/blob/2cc54867944d804f7033f0ff3f5e458ec579aabe/homeassistant/components/tuya/__init__.py#L193-L211) per capire come salvare un dato interno (il minuto di esecuzione, nello specifico) nella configurazione di Home Assistant, non mutabile, che richiede l'esecuzione di `async_update_entry` su una copia della stessa
- Ho tentato di modificare i sensori per fare in modo che derivassero da `RestoreSensor` anziché da `RestoreEntity`, come [suggerito dalla documentazione](https://developers.home-assistant.io/docs/core/entity/sensor/?_highlight=monetary#restoring-sensor-states) ufficiale di Home Assistant, tuttavia ho dovuto desistere perché la funzione `self.async_get_last_sensor_data()` può salvare solo 2 dati, cioè `native_value` e `native_unit_of_measurement` (un esempio [qui](https://github.com/jonathan-ek/solis_modbus/blob/b768066e07d92041f8cc57e4dc6d4a67c18334ca/custom_components/solis_modbus/number.py#L251-L253) oppure [qui](https://github.com/ckarrie/ha-netgear-plus/blob/8f0aa265319cc7c4cc7100a060ab16f0858426cd/custom_components/netgear_plus/netgear_entities.py#L110-L112)). Questi però non sono sufficienti per il nostro scopo, perché serve anche sapere se il sensore è disponibile (`self._available`, che al limite si potrebbe rendere implicito con `native_value = None`) ma soprattutto il nome della fascia corrente (`self._friendly_name`) per `PrezzoFasciaPUNSensorEntity`. Quindi, in definitiva, ho lasciato tutto com'era, sfruttando `self.async_get_last_extra_data()` e il dizionario personalizzato fornito da `def extra_restore_state_data(self)` che comunque ripristina `native_value` e non lo `state` come scrive la documentazione.
Loading

0 comments on commit bc759c6

Please sign in to comment.