Skip to content

feat(wsen-pads): Climate Station example with OLED Display.#373

Merged
nedseb merged 5 commits intomainfrom
feat/wsen-pads-climate-station
Apr 16, 2026
Merged

feat(wsen-pads): Climate Station example with OLED Display.#373
nedseb merged 5 commits intomainfrom
feat/wsen-pads-climate-station

Conversation

@MatteoCnda1
Copy link
Copy Markdown
Contributor

@MatteoCnda1 MatteoCnda1 commented Apr 10, 2026

Closes #332

Summary

Add a climate station example that combines WSEN-PADS (temperature + pressure) and HTS221 (humidity) on the SSD1327 128x128 OLED using steami_screen widgets.

The display shows:

  • A gauge arc colored by comfort level (green=ideal, red=hot, gray=cold)
  • Temperature as the main value (°C)
  • Humidity and pressure in the subtitle line
  • A comfort label (IDEAL / HOT / COLD / LOW P / HIGH P / OK)

Drivers used

  • wsen_pads — reads temperature() and pressure_hpa()
  • hts221 — reads humidity()
  • steami_screenScreen, SSD1327Display, gauge(), title(), value(), subtitle()

Test plan

  • Flash the firmware and run: make run SCRIPT=lib/wsen-pads/examples/station_env.py
  • Verify temperature, humidity and pressure readings update every second on the OLED
  • Verify the gauge arc color changes with comfort level (blow warm air → HOT/red, cool the board → COLD/gray)
  • Verify Ctrl+C cleanly clears the screen and powers off both sensors (no residual display, no battery drain)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new OLED-based “environment station” examples demonstrating real-time sensor readout and rendering on the SSD1327 128×128 display, combining WSEN-PADS (pressure/temperature) and HTS221 (humidity).

Changes:

  • Added station_env.py example under wsen-pads showing temperature/humidity/pressure + comfort label UI on the OLED.
  • Added env_station.py example under hts221 showing temperature/humidity UI with bars and comfort label on the OLED.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 9 comments.

File Description
lib/wsen-pads/examples/station_env.py New multi-sensor climate station example rendering live readings + bars + comfort label on SSD1327.
lib/hts221/examples/env_station.py New HTS221-only OLED station example with calibration, bar UI, and comfort label.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/wsen-pads/examples/station_env.py Outdated
import ssd1327
from wsen_pads import WSEN_PADS
from hts221 import HTS221

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 502363b: the file was fully rewritten using steami_screen widgets — all manual pixel drawing, spacing issues, and grayscale value errors are gone.

Comment thread lib/wsen-pads/examples/station_env.py Outdated
Comment on lines +8 to +12
spi = SPI(1)
dc = Pin("DATA_COMMAND_DISPLAY")
res = Pin("RST_DISPLAY")
cs = Pin("CS_DISPLAY")
display = ssd1327.WS_OLED_128X128_SPI(spi, dc, res, cs)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 502363b: the file was fully rewritten using steami_screen widgets — all manual pixel drawing, spacing issues, and grayscale value errors are gone.

Comment thread lib/wsen-pads/examples/station_env.py Outdated
Comment on lines +15 to +17
i2c = I2C(1)
pads = WSEN_PADS(i2c) # pression + temperature
hts = HTS221(i2c) # humidite
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 502363b: the file was fully rewritten using steami_screen widgets — all manual pixel drawing, spacing issues, and grayscale value errors are gone.

Comment thread lib/wsen-pads/examples/station_env.py Outdated
Comment on lines +74 to +80
def draw_bar_h(x, y, w, h, value, min_val, max_val, color=200):
draw_rect(x, y, w, h, 80)
ratio = (value - min_val) / (max_val - min_val)
ratio = max(0.0, min(1.0, ratio))
filled = int((w - 2) * ratio)
if filled > 0:
draw_fill_rect(x + 1, y + 1, filled, h - 2, color)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 502363b: the file was fully rewritten using steami_screen widgets — all manual pixel drawing, spacing issues, and grayscale value errors are gone.

Comment thread lib/wsen-pads/examples/station_env.py Outdated
Comment on lines +143 to +146
temp = pads.temperature() + OFFSET_TEMP
hum = hts.humidity() + OFFSET_HUM
pres = pads.pressure_hpa()+ OFFSET_PRES
hum = max(0.0, min(100.0, hum))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 502363b: the file was fully rewritten using steami_screen widgets — all manual pixel drawing, spacing issues, and grayscale value errors are gone.

Comment thread lib/hts221/examples/env_station.py Outdated
Comment on lines +7 to +12
spi = SPI(1)
dc = Pin("DATA_COMMAND_DISPLAY")
res = Pin("RST_DISPLAY")
cs = Pin("CS_DISPLAY")
display = ssd1327.WS_OLED_128X128_SPI(spi, dc, res, cs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was removed in a previous commit (c2f55d9). No longer applicable.

Comment thread lib/hts221/examples/env_station.py Outdated
Comment on lines +32 to +36
# Zone safe pour ecran rond : carré 90x90 centré => x:[19,109] y:[19,109]
SAFE_X = 19
SAFE_Y = 19
SAFE_W = 90
SAFE_H = 90
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was removed in a previous commit (c2f55d9). No longer applicable.

Comment thread lib/hts221/examples/env_station.py Outdated
Comment on lines +75 to +82
def draw_bar_h(x, y, w, h, value, min_val, max_val, color=200):
draw_rect(x, y, w, h, 80)
ratio = (value - min_val) / (max_val - min_val)
ratio = max(0.0, min(1.0, ratio))
filled = int((w - 2) * ratio)
if filled > 0:
draw_fill_rect(x + 1, y + 1, filled, h - 2, color)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was removed in a previous commit (c2f55d9). No longer applicable.

Comment thread lib/hts221/examples/env_station.py Outdated
Comment on lines +134 to +138
try:
temp = sensor.temperature() + OFFSET_TEMP
hum = sensor.humidity() + OFFSET_HUM
hum = max(0.0, min(100.0, hum))
print(f"T:{temp:.2f}C H:{hum:.2f}%")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was removed in a previous commit (c2f55d9). No longer applicable.

@MatteoCnda1 MatteoCnda1 force-pushed the feat/wsen-pads-climate-station branch from 7620597 to 5ff7af2 Compare April 10, 2026 11:56
@nedseb nedseb requested review from Charly-sketch and removed request for nedseb April 10, 2026 12:04
@nedseb
Copy link
Copy Markdown
Contributor

nedseb commented Apr 10, 2026

💡 Suggestion: cette PR utilise le SSD1327 directement. Le projet a maintenant steami_screen qui fournit des widgets prêts à l'emploi pour ce type d'affichage.

Pour une station météo, tu pourrais utiliser :

from steami_screen import Screen, SSD1327Display
display = SSD1327Display(ssd1327.WS_OLED_128X128_SPI(spi, dc, res, cs))
screen = Screen(display)

screen.clear()
screen.title("Meteo")
screen.value(temperature, label="Temp", unit="C")
screen.bar(humidity, max_val=100)
screen.subtitle("P: {:.0f} hPa".format(pressure))
screen.show()

Cela remplacerait le code de positionnement manuel. Le wrapper SSD1327Display gère la conversion de couleur automatiquement. Pas obligatoire, mais ça simplifierait pas mal le code.

@MatteoCnda1 MatteoCnda1 force-pushed the feat/wsen-pads-climate-station branch from 5ff7af2 to d83c38b Compare April 10, 2026 12:16
@Charly-sketch
Copy link
Copy Markdown
Contributor

Charly-sketch commented Apr 10, 2026

Review

Très bon travail sur cet exemple.
On voit clairement l’effort pour proposer quelque chose de concret et démonstratif : multi-capteurs, affichage OLED, calibration, indice de confort… c’est un exemple riche et utile pour comprendre comment combiner plusieurs drivers.

L’ensemble est globalement propre et fonctionne, mais il y a plusieurs points à améliorer pour être pleinement aligné avec les conventions du projet et améliorer la maintenabilité.


1. Complexité de l’exemple

L’exemple est assez long et contient beaucoup de logique de rendu (fonctions draw_*, gestion des formes, etc.)

Dans le dossier examples/, on essaie en général de garder :

  • des exemples simples
  • centrés sur l’utilisation des drivers

Ici, la partie graphique prend beaucoup de place par rapport à l’objectif principal.

Suggestion :
Tu peux utiliser le driver steami_screen qui vient d'être merge dans le main. Il a plusieurs fonctions utilitaires pour l'écran. Si tu veux l'avoir sur ta branche il va falloir faire :

git checkout main # te rendre sur la branche principale
git fetch # va chercher les changements sur la branche distante
git pull # les tire dans ta branche main locale 

git checkout feat/wsen-pads-climate-station # retour sur ta branche 
git rebase main  # incorpore les changements de main dans ta branche 

2. Utilisation directe de SSD1327

Suggestion : cette PR utilise le SSD1327 directement. Le projet a maintenant steami_screen qui fournit des widgets prêts à l'emploi pour ce type d'affichage.

Pour une station météo, tu pourrais utiliser :

from steami_screen import Screen, SSD1327Display

display = SSD1327Display(ssd1327.WS_OLED_128X128_SPI(spi, dc, res, cs))
screen = Screen(display)

screen.clear()
screen.title("Meteo")
screen.value(temperature, label="Temp", unit="C")
screen.bar(humidity, max_val=100)
screen.subtitle("P: {:.0f} hPa".format(pressure))
screen.show()

Cela remplacerait le code de positionnement manuel. Le wrapper SSD1327Display gère la conversion de couleur automatiquement.
Pas obligatoire, mais ça simplifierait pas mal le code.


3. Mélange anglais / français

Exemples :

  • "CLIMAT"
  • "ERREUR"

Le repo est en anglais, donc il faut rester cohérent.

Suggestion :

  • passer tous les textes en anglais (CLIMATE, ERROR, etc.)

4. Formatting / Ruff / newline

Il y a des erreurs de formatage et des problèmes de saut de ligne en fin de fichier, ce qui fait échouer les checks.

Correction rapide :

make lint-fix "chemin/de/ton/driver"

Tu peux aussi configurer VS Code pour éviter ça automatiquement :

{
  "files.insertFinalNewline": true,
  "editor.formatOnSave": true
}

5. Commitlint

Erreur sur le commit message :

feat(wsen-pads): Climate Station example with OLED Display

Il manque un point final.

Correction :

git commit --amend -m "feat(wsen-pads): Climate Station example with OLED display."

6. README non mis à jour

L’exemple n’est pas ajouté dans le README du driver.

À faire :
Ajouter une ligne dans le tableau des exemples. (Pense à y mentionner la dépendance au driver hts221.)


7. Descrition de la PR

Dans la description de la PR, tu as oublié les espaces entres les # et les titres, c'est pour ça qu'ils ne s'affichent pas correctement. Tu peux utiliser l'onglet "Preview" si jamais tu as un doute sur le rendu.


Conclusion

Exemple très intéressant et complet, clairement utile pour démontrer les capacités de la carte.
Pour être parfaitement aligné avec le projet, il faudrait surtout :

  • simplifier la partie affichage avec steami_screen (pense à aller voir les exemples)
  • corriger les commentaires
  • passer les outils de lint correctement

Avec ces ajustements, ce sera un excellent exemple pour le repo.

@MatteoCnda1 MatteoCnda1 force-pushed the feat/wsen-pads-climate-station branch 2 times, most recently from 30fdae5 to 557917e Compare April 13, 2026 09:31
@MatteoCnda1 MatteoCnda1 changed the title feat(wsen-pads): Climate Station example with OLED Display feat(wsen-pads): Climate Station example with OLED Display. Apr 13, 2026
@MatteoCnda1
Copy link
Copy Markdown
Contributor Author

Thank you for the detailed review! Here is a summary of the changes made to address all the points raised:

  1. Simplified display code using steami_screen
    Replaced all manual drawing functions (draw_*, draw_circle, draw_bar_h, etc.) with the steami_screen widget library as suggested. The example now uses Screen, SSD1327Display, screen.clear(), screen.title(), screen.value(), screen.bar(), screen.subtitle() and screen.show().

  2. Removed env_station.py
    The standalone HTS221-only example has been removed to keep the PR focused on the multi-sensor use case.

  3. English only
    All French strings (CLIMAT, ERREUR, etc.) have been replaced with their English equivalents (CLIMATE, ERROR, etc.).

  4. Lint and formatting
    All ruff errors have been fixed using ruff check --fix. The file now has a proper final newline and no trailing whitespace. VS Code has been configured with files.insertFinalNewline and editor.formatOnSave to prevent these issues in the future.

MatteoCnda1 and others added 5 commits April 16, 2026 22:00
Major rewrite of the station_env example:

1. Use steami_screen (Screen, SSD1327Display, gauge, title, value,
   subtitle) instead of 100+ lines of pixel-by-pixel manual drawing
   (draw_hline, draw_vline, draw_rect, draw_fill_rect, draw_circle).
   The native framebuf primitives behind steami_screen are implemented
   in C and are orders of magnitude faster than Python pixel loops.

2. Remove fake calibration that forced readings toward arbitrary "ideal"
   values (20C, 50%RH, 1013hPa). A sensor reading 23C at startup was
   being shifted to 20C, making every subsequent reading wrong by -3C.
   The example now shows raw sensor values. For real calibration, use
   steami_config (see calibrate_temperature.py).

3. Translate all UI text and comments from French to English to match
   the project convention.

4. Add try/except/finally with power_off() for both sensors so Ctrl+C
   does not leave WSEN-PADS and HTS221 running.

5. Use named comfort thresholds (TEMP_MIN/MAX, HUM_MIN/MAX, PRES_MIN/MAX)
   instead of inline magic numbers.
@nedseb nedseb force-pushed the feat/wsen-pads-climate-station branch from d773295 to 502363b Compare April 16, 2026 20:00
Copy link
Copy Markdown
Contributor

@nedseb nedseb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matteo, j'ai réécrit l'exemple en profondeur dans le commit 502363b. Voici le résumé des changements :

1. Migration vers steami_screen — Les ~100 lignes de dessin pixel-par-pixel (draw_hline, draw_vline, draw_rect, draw_fill_rect, draw_circle, draw_bar_h) ont été remplacées par les widgets steami_screen : screen.gauge(), screen.title(), screen.value(), screen.subtitle(). Les primitives natives de framebuf (implémentées en C) sont des ordres de grandeur plus rapides que les boucles display.pixel() en Python.

2. Suppression de la fausse calibration — Le code forçait les lectures vers des valeurs "idéales" arbitraires (20°C, 50%RH, 1013 hPa). Un capteur mesurant 23°C au démarrage était décalé à 20°C, ce qui faussait toutes les lectures suivantes de -3°C. L'exemple montre maintenant les valeurs brutes des capteurs. Pour une vraie calibration de température, le projet fournit steami_config (cf. calibrate_temperature.py).

3. Traduction en anglais — Toute l'interface ("CLIMAT" → "CLIMATE", "CHAUD" → "HOT", etc.) et les commentaires suivent désormais la convention du projet.

4. Cleanup try/finally — Ctrl+C éteint proprement l'écran et coupe les deux capteurs (pads.power_off(), hts.power_off()).

5. Constantes nommées — Les seuils de confort sont extraits en constantes (TEMP_MIN/MAX, HUM_MIN/MAX, PRES_MIN/MAX) au lieu de nombres magiques inline.

Le fichier passe de 173 à 91 lignes, tout en étant plus fonctionnel (gauge arc couleur selon le confort, cleanup propre, lectures correctes).

Branche rebasée sur main. Prêt à merger.

@nedseb nedseb merged commit e9d5539 into main Apr 16, 2026
9 checks passed
semantic-release-updater Bot pushed a commit that referenced this pull request Apr 16, 2026
# [0.22.0](v0.21.0...v0.22.0) (2026-04-16)

### Features

* **wsen-pads:** Climate Station example with OLED Display. ([#373](#373)) ([e9d5539](e9d5539))
@semantic-release-updater
Copy link
Copy Markdown

🎉 This PR is included in version 0.22.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@nedseb nedseb deleted the feat/wsen-pads-climate-station branch April 16, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(wsen-pads): Add climate station example with multi-sensor OLED display.

4 participants