## SOLID princípy v IoT #### Prečo aj firmvér potrebuje dobrý dizajn [Mirek Biňas](https://bletvaska.github.io) / [**OSS Conf Žilina 2026**](https://ossconf.fri.uniza.sk/)
![Smatr Department: Architecture](images/smart.department-architecture.png) notes: - uz som tu hovoril viackrat na temu Internetu veci, ale pravidelne som hovoril o infrastrukture ako celku - dnes vsak budem hovorit o koncovych bodoch architektury - o senzoroch a akcnych clenoch
![THSensor](images/thsensor-illustration.png) notes: - dnes vsak budem hovorit o koncovych bodoch architektury - o senzoroch a akcnych clenoch
## Firmvér > Softvér trvalo uložený v pamäti mikrokontroléra, ktorý priamo riadi jeho hardvér a vykonáva špecifickú funkciu zariadenia. Spustí sa po zapnutí mikrokontroléra. notes: - dnes chcem hovorit o tom, akych pravidiel sa drzat pri programovani firmveru na mikrokontroleri
[![SOLID](images/solid-principles.webp)](https://techwayfit.com/blogs/design-principles/solid-principles/)
## Single Responsibility Principle (SRP) > A class should have one and only one reason to change. > -- [Robert C. Martin](https://en.wikipedia.org/wiki/Single-responsibility_principle)
### Výhody * kód je ľahšie čitateľný a pochopiteľný * zmena jednej vlastnosti neovplyvní ostatné * triedy sa dajú testovať izolovane * jednoduchšie znovupoužitie
## Stavový stroj celý životný cyklus zariadenia je organizovaný ako stavový stroj
![Smart Sensor: State Diagram](images/smart.sensor-state.diagram.png)
## Návrhový vzor Stav ![](images/state.design.pattern.png)
## Open/Closed Principle (OCP) > Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. > -- [Bertrand Meyer](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle)
### Výhody * škálovateľnosť - nový stav / príkaz / zariadenie sa dá pridať bez zmeny aktuálneho kódu * paralelný vývoj na viacerých triedach bez konfliktu * kód, ktorý sa nemení, sa nepokazí
## Liskov Substitution Principle (LSP) > Objects of a superclass should be replacable with objects of its subclasses. > -- [Barbara Liskov](https://en.wikipedia.org/wiki/Liskov_substitution_principle)
![DHT Sensors](images/dht.sensors.png) notes: - predstavme si situaciu, ze robime prave senzor teploty - aktualna implementacia - pouzivame senzor DHT11
![TMP36 Sensor](images/tmp.sensor.png) notes: - potom pride sef a povie, ze ked vymenime senzor, tak rozsah pracovnych teplot bud vacsi, ako ma DHT11 - a dokonca budeme vediet citat aj desatinne hodnoty
![DS1820 Sensor](images/ds1820.sensor.png) notes: - ale ked ho vymenime za tento, tak to bude lacnejsie a bude mat nizsiu spotrebu
### ...a máme problém * každý používa iné knižnice * každý používa inú komunikačnú zbernicu * každý má iné požiadavky na piny * potrebujeme ručne upraviť všetky miesta, kde sa používa: * inicializácia * meranie údajov * webové rozhranie * príkaz v termináli
```python from machine import Pin from dht import DHT11 # init sensor sensor = DHT11(Pin(4)) # measure data sensor.measure() # get temperature temp = sensor.temperature() print(temp) ``` ```python from machine import ADC, Pin # init sensor sensor = ADC(Pin(26)) # read analog value value = sensor.read_u16() # convert to voltage voltage = value * (3.3 / 65535) # convert voltage to temperature temp = (voltage - 0.5) * 100 print(temp) ``` ```python import time from machine import Pin import onewire, ds18x20 # init sensor ow = onewire.OneWire(Pin(4)) sensor = ds18x20.DS18X20(ow) # find sensor roms = sensor.scan() # measure temperature sensor.convert_temp() # wait for conversion time.sleep_ms(750) # get temperature temp = sensor.read_temp(roms[0]) print(temp) ``` notes: - pre ilustráciu - takto vyzerajú príslušné fragmenty kódu
### Čo majú všetky tri senzory teploty spoločné?
### Potomok vie nahradiť predka ```python # predok každého teplotného senzora class TemperatureSensor: def temperature(self) -> float: raise NotImplementedError ``` ```python # implementácia potomka pre DHT11 from machine import Pin from dht import DHT11 class DHT11(TemperatureSensor): def __init__(self, pin: int): self.sensor = DHT11(Pin(pin)) def temperature(self) -> float: self.sensor.measure() return self.sensor.temperature() ```
## Komponent Komponent je **samostatná**, **zapúzdrená jednotka** systému, ktorá má **jasne definované rozhranie** a poskytuje **konkrétnu funkcionalitu**.
## Interface Segregation Principle (ISP) > Clients should not be forced to depend upon methods that they do not use. > -- [Robert C. Martin](https://en.wikipedia.org/wiki/Interface_segregation_principle)
### WTF? * ak by sme mali len DHT11, tak by spoločný predok vyzeral takto: ```python class SensorDevice: def temperature(self) -> float: raise NotImplementedError def humidity(self) -> float: raise NotImplementedError ```
### ...a máme problém * ale TMP36 ani DS1820 nemerajú vlhkosť, takže `humidity()` nepotrebujú * ale senzor svetla potrebuje `intensity()`, ale nepotrebuje `temperature()` a `humidity()` * ale senzor tlaku potrebuje `pressure()`, ale nepotrebuje `temperature()`, `humidity()` ani `intensity()`
### Riešenie * miesto jedného mega-šupa-bomba-špica rozhrania vytvoríme niekoľko menších rozhraní
## Mixins > Mixin je trieda, ktorá pridáva jednu alebo viacero konkrétnych vlastností alebo správanie inej triede.
## Dependency Inversion Principle (DIP) > Abstractions should not depend upon details. Details should depend upon abstractions. > -- [Robert C. Martin](https://en.wikipedia.org/wiki/Dependency_inversion_principle)
### O čo ide? * vysokoúrovňová logika aplikácie by nemala byť pevne naviazaná na konkrétnu implementáciu, ale na abstrakciu
[![SOLID](images/solid-principles.webp)](https://techwayfit.com/blogs/design-principles/solid-principles/)
## Prečo SOLID na mikrokontroléroch? * ak blikáš len LED-kou, tak nemusíš * jednoduchšia výmena hardvéru - lebo abstrakcia/rozhranie * lepšia testovateľnosť - zapúzdrené správanie * jednoduchšia rozšíriteľnosť / škálovateľnosť * znovupoužiteľnosť kódu * dobrá tímová práca
## Otázky?
![qr code](https://api.qrserver.com/v1/create-qr-code/?data=https://bit.ly/4eXGujh&size=300x300) (**https://bit.ly/4eXGujh**)