Modbus käytännössä — Home Assistantin integraatio

Written by

in

Tämä ohje selittää Modbus-protokollan perusteet ja sen käytännön toteutuksen Home Assistantissa. Ohje on kirjoitettu EnergyHub-projektin näkökulmasta — laitekohtaiset rekisterikartat löytyvät omista ohjeistaan: Sungrow Modbus + tehonrajoitus ja Thermia Modbus + EVU/Boost.

Modbusin rooli EnergyHubissa

Modbus on tiedonsiirtoprotokolla, ei optimointijärjestelmä. EnergyHubissa Modbusin tehtävä on välittää mittausdata ylöspäin ja ohjauskomennot alaspäin. Päätökset tehdään ylemmissä kerroksissa — Node-REDin Priority Resolverissa — jolloin laiteintegraatiot pysyvät yksinkertaisina ja uudelleenkäytettävinä. Sama Modbus-konfiguraatio toimii riippumatta siitä mitä optimointilogiikka päättää.

Mikä on Modbus

Modbus on teollisuusautomaation tiedonsiirtoprotokolla joka on kehitetty 1979. Se on yksinkertainen, luotettava ja laajasti tuettu — löytyy inverttereistä, lämpöpumpuista, energiamittareista ja sadoista muista laitteista.

EnergyHubissa Modbus on se yhteys jonka kautta Home Assistant lukee laitteiden tilat ja kirjoittaa ohjauskomennot. Ilman Modbus-integraatiota invertteri ja lämpöpumppu olisivat mustia laatikoita.

Modbus RTU vs Modbus TCP

Modbus on saatavilla kahdessa muodossa:

Modbus RTU — sarjaväylä (RS-485). Laitteet kytketään fyysisellä kaapelilla. Käytetään yleensä vanhemmissa laitteissa tai laitteissa joissa ei ole verkkoliitäntää. Thermian vanhemmissa malleissa (esimerkiksi Diplomat-sarja) Modbus toteutetaan tyypillisesti erillisen väyläkortin kautta RTU-väylällä.

Modbus TCP — TCP/IP-verkko. Laite kytketään lähiverkkoon ja kommunikaatio tapahtuu IP-osoitteen ja portin (oletus 502) kautta. Moderni ja helpompi integroida Home Assistantiin. Sungrow-invertteri tukee Modbus TCP:tä, samoin Thermian Genesis-alustan pumput (mm. Calibra ja Athena) suoraan RJ45-liitännän kautta — tässä projektissa käytetty Calibra 12 ajaa Modbus TCP:tä natiivisti ilman lisäkortteja.

EnergyHubissa käytetään Modbus TCP:tä — ei tarvita erillisiä kaapeleita tai RS-485-adaptereita.

Rekisterityypit

Modbus-laite tarjoaa neljää eri rekisterityyppiä:

TyyppiFunktion koodiSuuntaKuvaus
Coil1 (luku), 5 (kirjoitus)R/WYksibittinen boolean
Discrete Input2RYksibittinen boolean, vain luku
Holding Register3 (luku), 6 (kirjoitus)R/W16-bittinen arvo, luettava ja kirjoitettava
Input Register4R16-bittinen arvo, vain luku

Käytännössä:

  • Mittausdata (lämpötilat, tehot, virrat) → Input Register
  • Asetusarvot ja ohjauskomennot → Holding Register
  • Binääriset tilat (käynnissä/pysähdyksissä) → Coil tai Discrete Input

Osoitteistus — tärkein kompastuskivi

Modbus-dokumentaatioissa käytetään kahta eri osoitejärjestelmää jotka sekoittavat helposti:

De Facto -osoitteet — dokumentaatioissa yleisin tapa:

  • Coil: 00001–09999
  • Discrete Input: 10001–19999
  • Input Register: 30001–39999
  • Holding Register: 40001–49999

Raw-osoitteet (0-pohjainen) — mitä Home Assistant käyttää YAML:ssa:

  • Holding Register 40006 → address: 5
  • Input Register 30014 → address: 13

Kaava: HA address = De Facto address – tyypin offset – 1

De FactoHA addressTyyppi
400065holding
3001413input
10202201discrete input

Tämä on yleisin syy siihen miksi Modbus-integraatio ei toimi ensi yrittämällä.

Skaalaus

Monet laitteet tallentavat tiedot 16-bittisinä kokonaislukuina (0–65535) ja käyttävät skaalausta desimaalien esittämiseen. Osa laitteista käyttää myös 32-bittisiä arvoja kahden rekisterin yli (data_type: int32, uint32 tai float32). Thermia ja Sungrow käyttävät pääosin 16-bittisiä kokonaislukuja skaalauksella — Sungrow’lla esimerkiksi energialaskurit ovat kuitenkin 32-bittisiä kahden rekisterin yli.

Thermia-lämpöpumppu käyttää kerrointa 100:

  • Rekisteriarvo 2150 = 21,50 °C
  • HA:ssa: scale: 0.01

Negatiiviset luvut esitetään kahden komplementtina:

  • -1 = 65535
  • -5 = 65531

Tämä näkyy HA:ssa data_type: int16 — käytä int16 kun arvo voi olla negatiivinen (ulkolämpötila, teho), uint16 kun arvo on aina positiivinen.

Home Assistantin Modbus-konfiguraatio

Perusrakenne configuration.yaml:ssa tai packages-tiedostossa:

yaml

modbus:
  - name: laite_nimi        # Uniikki nimi hubille
    type: tcp               # tcp tai rtu
    host: 192.168.x.x       # Laitteen IP-osoite
    port: 502               # Modbus TCP oletus
    delay: 2                # Sekuntia ennen ensimmäistä kyselyä
    timeout: 5              # Yhteyden aikakatkaisu
    retries: 3              # Uudelleenyritykset
    retry_on_empty: true    # Yritä uudelleen tyhjällä vastauksella

    sensors:
      - name: sensori_nimi
        unique_id: sensori_nimi
        slave: 1              # Slave ID (yleensä 1)
        address: 13           # Raw-osoite (ei De Facto)
        input_type: input     # input, holding, coil, discrete_input
        data_type: int16      # int16, uint16, int32, uint32, float32
        scale: 0.01           # Skaalauskerroin
        precision: 1          # Desimaaleja
        unit_of_measurement: "°C"
        scan_interval: 60     # Kyselyväli sekunteina

Kirjoitusrekisterit

Holding Register -kirjoitus HA:sta:

yaml

- action: modbus.write_register
  data:
    hub: laite_nimi     # Sama kuin name: yllä
    slave: 1
    address: 5          # Raw-osoite
    value: 2200         # Kirjoitettava arvo (ei skaalattu)

Tärkeä huomio: value on aina raaka-arvo ilman skaalausta. Jos haluat kirjoittaa 22,0 °C ja scale on 0.01, kirjoita arvo 2200.

Coil-kirjoitus:

yaml

- action: modbus.write_coil
  data:
    hub: laite_nimi
    slave: 1
    address: 8
    state: true

Kirjoitus ei ole valmis ennen readbackia

Onnistunut modbus.write_register-kutsu tarkoittaa vain että kirjoituspyyntö lähti — ei että arvo on laitteessa voimassa. Kirjoitus voi hukkua Modbus-katkoon, laite voi hylätä arvon hiljaa tai rekisteri voi olla eri kuin luultiin. Siksi jokaiseen kirjoitettavaan rekisteriin kannattaa konfiguroida myös lukusensori (tai number-entiteetti, joka pollaa arvoa), ja ohjauslogiikan pitää verrata kirjoitettua arvoa takaisin luettuun ennen kuin kirjoitus katsotaan tehdyksi.

EnergyHubissa tämä on viety periaatteeksi asti: comfort wheel -kirjoitus pysyy pending-tilassa kunnes readback vahvistaa sen, ja Smart Grid -releohjausten toteuma varmistetaan tilarekisteristä uudelleenyrityksin. Toteutukset on kuvattu Thermia-ohjeessa — mutta periaate on laitteesta riippumaton: komento ei ole sama kuin toteuma.

Scan interval -suositukset

Kyselyväli vaikuttaa sekä datan tuoreuteen että verkon kuormitukseen. Liian tiheä kysely voi aiheuttaa ongelmia joillakin laitteilla.

DataSuositeltu väli
Teho, virta, jännite10–30 s
Lämpötilat30–60 s
Käyttötila, tilat30 s
Päivätuotanto, tuntilukemat60–300 s
Elinikäiset laskurit300 s

Validointi ja debuggaus

Tarkista rekisteriarvot suoraan:

bash

# Asenna modbus-cli (vaihtoehtoja: mbpoll, pymodbus, Windows: Modbus Poll)
pip install modbus-cli --break-system-packages

# Lue 5 holding registeriä osoitteesta 0
modbus read 192.168.x.x:502 %MW0+5

# Lue input registeri
modbus read 192.168.x.x:502 %IW13

HA:n Modbus-lokit:

bash

docker logs homeassistant 2>&1 | grep -i modbus | tail -20

Tyypilliset virheet:

VirheSyyRatkaisu
isError TrueVäärä rekisteri tai osoiteTarkista De Facto → raw-muunnos
~200°C lämpötilaVäärä skaalausVaihda scale: 0.01
Connection refusedVäärä IP tai porttiTarkista ping ja portti 502
TimeoutLaite ei vastaaLisää timeout ja retries
Negatiiviset arvot väärinVäärä data_typeVaihda uint16 → int16
Kirjoitus ”onnistuu” mutta mikään ei muutuKirjoitus hukkui tai väärä rekisteriLisää readback-luku ja vertaa arvoa

Modbus ja muut valmistajat

Modbus-rekisterikartat ovat laitekohtaisia — eri valmistajilla on omat osoitteensa ja skaalauksensa. SunSpec-standardi pyrkii yhtenäistämään aurinkoenergialaitteiden rekisterikartat, mutta kaikki valmistajat eivät noudata sitä.

Esimerkkejä EnergyHub-yhteensopivista laitteista:

  • Invertterit: Sungrow, Fronius, SMA, ABB, Huawei SUN2000, GoodWe
  • Lämpöpumput: Thermia, Nibe, Mitsubishi, Daikin, Vaillant
  • Energiamittarit: useimmat DIN-kiskoon asennettavat mittarit

Ennen integraatiota tarkista aina laitteen valmistajan Modbus-dokumentaatio ja validoi rekisteriarvot käytännössä — dokumentaatio ei aina vastaa todellisuutta.

Dokumentaatio ei aina riitä

Käytännössä Modbus-integraation suurin työ ei yleensä ole YAML-konfiguraatio vaan rekisterien validointi. Valmistajan dokumentaatio voi sisältää virheitä, rekistereitä voi puuttua tai ohjelmistoversio voi muuttaa toimintaa ilman erillistä ilmoitusta.

EnergyHub-projektissa esimerkiksi osa Thermian rekistereistä jouduttiin varmistamaan käytännön testauksella ennen käyttöönottoa — dokumentaation mukaiset arvot eivät aina vastanneet mitattuja arvoja. Sungrow-invertterissä rekisteriosoitteet poikkesivat yleisestä dokumentaatiosta firmware-version mukaan.

Käytännön validointiperiaate: lue ensin, vertaa dokumentaatioon, kirjoita vasta kun arvo on varmennettu — ja lue kirjoituksen jälkeen takaisin, jotta tiedät että arvo meni perille.

Vastuuvapauslauseke

Modbus-kirjoitusoperaatiot tehdään omalla vastuulla. Virheelliset kirjoitukset voivat aiheuttaa laitteen virhetoiminnan. Testaa aina ensin lukemalla ja varmistamalla arvo ennen kirjoitusta.