community italiana di domotica personale
 
Gestire un UPS con Raspberry Pi tramite NUT (“Network UPS Tools”) con Docker (su Raspberry Pi OS)

Gestire un UPS con Raspberry Pi tramite NUT (“Network UPS Tools”) con Docker (su Raspberry Pi OS)

9 minuti di lettura
Scopi della guida:
  • Gestire in modo standard, indipendentemente da marca e modello, un qualunque gruppo di continuità (UPS) compatibile con NUT, tramite Raspberry, usando Docker
  • Livello di difficoltà: basso
Concetti affrontati:
  • Configurazione software
Componenti software utilizzate:
Prerequisiti:
  • Raspberry Pi configurato e funzionante con sistema operativo Raspberry Pi OS
COMPONENTI FISICI UTILIZZATI:
PROGETTO MAGGIORMENTE INDICATO PER:

Raspbian Logo

Note e disclaimer
  • qualsiasi eventuale modifica agli impianti domestici dev'essere progettata ed realizzata SOLO da personale qualificato;
  • qualsiasi modifica attuata in proprio è a propria responsabilità personale nonché a proprio rischio e pericolo (i contenuti della presenta pagina hanno puro scopo didattico);
  • qualsiasi modifica attuata in proprio a un dispositivo ne fa decadere garanzia, omologazioni e certificazioni di qualità.
Revisione guida: 2.0

NUT su Docker

Abstract

Abbiamo già affrontato in diverse occasioni il tema della continuità elettrica, ovvero la possibilità di rendere la nostra domotica (o altro) costantemente operativa, specie in caso di black-out. Per farlo è necessario dotarsi di un UPS (Uninterruptable Power Supply), il quale sostanzialmente è un pacco di batterie che, in caso di assenza di alimentazione elettrica continua a fornire energia – per lo meno fino alla sua completa scarica.

UPS APCModelli di UPS ne esistono centinaia per non dire migliaia: al tema di come e perché scegliere un UPS adeguato alle proprie esigenze abbiamo dedicato una scheda apposita; in tale scheda, nelle conclusioni, abbiamo fatto riferimento all’esistenza di UPS dotati di interfaccia USB la quale consente, in molti casi, di collegare l’unità a un computer al fine di verificarne lo stato operativo, quello di carica rimanente e moltissimi altri parametri. In alcuni casi, essi utilizzano porte seriali oppure una qualche connessione di rete (che sfrutti SNMP, Eaton, MGE XML/HTTP via TCP/IP).

In questa guida prenderemo in analisi l’adozione – su Raspberry Pi dotato di sistema operativo Raspberry Pi OS – dei cosiddetti “Network UPS Tools” (o “NUT”), un pacchetto di software concepiti espressamente allo scopo di riuscire a “dialogare” con l’UPS (indipendentemente dalla tipologia di interfaccia, di marca, del modello o dalle caratteristiche) e standardizzarne così non solo la consultazione delle misure ma anche l’eventuale esecuzione di comandi specifici verso di esso.

L’adozione dei NUT non solo abilita l’esecuzione di comandi e di interrogazioni tramite riga di comando Raspberry Pi OS, ma anche all’integrazione in domotica verso i più disparati HUB personali come, per esempio, Home Assistant.

N.b. Gli utilizzatori di un’eventuale installazione Home Assistant OS debbono fare riferimento a quest’altra guida e non alla presente, la quale è dedicata solo agli utenti Raspberry Pi OS@Raspberry Pi o, più genericamente, a installazioni Linux.

Altre guide e progetti dedicati a NUT:

Si parte

Assunti

Per questa guida utilizzeremo a mo’ d’esempio un UPS Tecnoware Era Plus 1100 – non foss’altro perché lo abbiamo in redazione e si tratta di un modello piuttosto diffuso. Come si capirà facilmente nella proseguimento della lettura, in realtà i modelli coi quali questa guida è applicabile sono tantissimi.

Si assume dunque di possedere un Raspberry Pi già configurato con Raspberry Pi OS e collegato in rete domestica, oltre ovviamente a un UPS compatibile (vedremo come) con NUT. Nell’esempio del Tecnoware Era Plus 1100, si immagina tale UPS connesso dal punto di vista logico al Raspberry tramite cavo USB type B.

Cosa sono i NUT

Come spiegato nell’Abstract, NUT è un insieme di software utile a interfacciarsi in modo standard a un UPS dotato di interfaccia USB, seriale o di rete (via SNMP, Eaton o MGE XML/HTTP su TCP/IP).

I NUT (per l’appunto un insieme di tool) sono sostanzialmente composti da:

  • un driver per comunicare con l’UPS tramite qualsiasi interfaccia e protocollo supportati, trasformando tale comunicazione in API locali standard;
  • un demone (un servizio) che funga da interfaccia tra il driver e qualunque altro interlocutore (per esempio il client che segue, o gli HUB personali);
  • un client a riga di comando, per monitorare, comandare e/o interrogare l’UPS (o gli UPS).

Scelta del driver

Non tutti gli UPS con interfacciamento USB/seriale/di rete sono necessariamente compatibili con NUT, anche se solitamente la probabilità è piuttosto alta.

Come abbiamo spiegato anche nella scheda dedicata alla scelta del proprio UPS, esiste una tabella di riferimento che elenca tutti i modelli compatibili con i Network UPS Tools: se il proprio UPS è presente in quella lista, è dunque possibile controllarlo con i NUT. Una volta trovato il proprio modello è necessario segnarsi da parte il driver corrispondente (colonna “Driver”, per l’appunto), informazione fondamentale per l’esecuzione dei prossimi passi.

N.b. Non sempre i modelli sono puntualmente elencati in tabella. Per esempio, proprio nel caso del nostro Tecnoware 1100 è riportato in pratica solo il brand Tecnoware, ma non il modello specifico. Utilizzando comunque il driver genericamente indicato (blazer_ser), l’integrazione verso i NUT ha funzionato alla perfezione, come infatti vedremo a seguire.

Collegamento fisico all’UPS

Prima di avventurarci nell’installazione software, colleghiamo l’UPS (acceso) a una porta USB di Raspberry, dopodiché riavviamo quest’ultimo.

Lo scopo è quello di lasciare assegnare una porta logica all’UPS: per scoprirla (servirà per la configurazione a seguire) andiamo a utilizzare uno script come da nostra guida.

Eseguito lo script, nel caso dell’UPS Tecnoware 1100 del nostro esempio apparirà in elenco una porta etichettata logicamente come “INNO_TECH_USB_to_Serial“: la porta indicata alla sua sinistra (per esempio /dev/bus/usb/001/003) sarà ciò che ci serve.
Segnamocela da parte.

N.b. Altri UPS, ovviamente, potrebbero apparire con etichette descrittive diverse. Solitamente sono sufficientemente “parlanti” tali da capire quale sia la porta assegnata.

Installare Docker

Installare Docker su Raspberry Pi dotato di sistema operativo Raspberry Pi OS è piuttosto semplice, esiste una procedura completamente automatica e una manuale. Entrambe le procedure sono illustrate in dettaglio in questa breve guida.

Se si ha già provveduto all’installazione di Docker, va da sé che questo passaggio possa essere saltato.

Creare la password

Prima di avviare NUT, è necessario creare un semplice file contenente la password di accesso ai servizi NUT (da associare poi a un nome utente, come vedremo a seguire.

Eseguire:

sudo nano /home/pi/nut-upsd-password

e, nell’editor, inserire solo la password scelta.
Uscire salvando (CTRL+X, Y, invio).

Istanziare NUT su Docker

Una volta installato Docker è dunque il momento di installare (o meglio, “istanziarvi sopra”) NUT.

In ambito Docker, l’istanziamento dell’applicazione può essere effettuato tramite esecuzione di un comando manuale (più immediato) oppure tramite una configurazione del tool di gestione Docker Compose, approccio inizialmente più ostico ma che consigliamo per tutta una serie di motivi. Entrambe le scelte sono valide, ma in prospettiva (specie in ottica di aggiornamento) imparare ad usare Docker Compose è altamente consigliato.

ATTENZIONE: affinché i comandi a seguire funzionino, è necessario aver aggiunto Docker al gruppo sudoers, come spiegato in guida d’installazione Docker.

Tramite comando “docker run”

Istanziamo dunque NUT su Docker tramite il comando che segue via terminale (da CLI, via SSH oppure con control-alt-t da interfaccia desktop):

docker run --name nut-upsd --detach -v /home/pi/nut-upsd-password:/run/secrets/nut-upsd-password --env PORT="PORTA_LOGICA" --env NAME="NOME_UPS" --env DESCRIPTION="DESCRIZIONE_UPS" --env DRIVER="DRIVER_SCELTO" --env API_USER="USERNAME" -p 3493:3493 --privileged --restart always instantlinux/nut-upsd

Alcuni parametri del comando, però, vanno personalizzati come segue:

–env PORT al posto di PORTA_LOGICA va indicata la porta precedentemente identificata (eg. /dev/bus/usb/001/003) oppure “auto“, se si è fortunati ci pensa il sistema a identificarla
–env NAME al posto di NOME_UPS va indicato il nome logico da assegnare all’UPS (eg. tecnoware)
–env DESCRIPTION al posto di DESCRIZIONE_UPS va indicata una label descrittiva dell’UPS (eg. Tecnoware)
–env DRIVER al posto di DRIVER_SCELTO va indicato il driver corretto per il proprio UPS (eg. blazer_ser)
–env API_USER al posto di USERNAME va indicato il nome utente scelto per collegarsi al servizio (eg. master)

 con un comando finale e complessivo simile a questo:

docker run --name nut-upsd --detach -v /home/pi/nut-upsd-password:/run/secrets/nut-upsd-password --env PORT="/dev/bus/usb/001/003" --env NAME="tecnoware" --env DESCRIPTION="tecnoware" --env DRIVER="blazer_ser" --env API_USER="nomeutente" -p 3493:3493 --privileged --restart always instantlinux/nut-upsd

lanciare quindi il proprio comando e attendere il completamento della procedura.
Al termine, verifichiamo che tutto sia andato per il verso giusto:

docker logs nut-upsd

nel log dovremmo trovare qualcosa come:

0.000000 UPS: tecnoware@localhost (master) (power value 1)
0.000059    debug level is '1'
0.000749    Trying to connect to UPS [tecnoware@localhost]
0.001803    Logged into UPS tecnoware@localhost 

Congratulazioni: NUT è ora operativo.

N.b. In caso di errori, verificare sulla pagina del container Docker che non sia presente qualche parametro specifico per il proprio UPS, necessario per l’avvio corretto, come per esempio capita con –env SERIAL (non incluso nel nostro comando di esempio), o altri.

Tramite Docker Compose

Se astutamente si sceglie di utilizzare Docker Compose, allora è semplicemente necessario aggiungere al proprio file docker-compose.yaml la seguente configurazione (sotto il bocco services):

  nut-upsd:
    container_name: nut-upsd
    image: instantlinux/nut-upsd
    volumes:
    - "/home/pi/nut-upsd-password:/run/secrets/nut-upsd-password"
    environment:
    - "PORT=PORTA_LOGICA"
    - "NAME=NOME_UPS"
    - "DESCRIPTION=DESCRIZIONE_UPS"
    - "DRIVER=DRIVER_SCELTO"
    - "API_USER=USERNAME"
    network_mode: host
    privileged: true
    restart: always

Alcuni parametri della configurazione, però, vanno personalizzati come segue:

–env PORT al posto di PORTA_LOGICA va indicata la porta precedentemente identificata (eg. /dev/bus/usb/001/003) oppure “auto“, se si è fortunati ci pensa il sistema a identificarla
–env NAME al posto di NOME_UPS va indicato il nome logico da assegnare all’UPS (eg. tecnoware)
–env DESCRIPTION al posto di DESCRIZIONE_UPS va indicata una label descrittiva dell’UPS (eg. Tecnoware)
–env DRIVER al posto di DRIVER_SCELTO va indicato il driver corretto per il proprio UPS (eg. blazer_ser)
–env API_USER al posto di USERNAME va indicato il nome utente scelto per collegarsi al servizio (eg. master)

 con una configurazione finale simile a questa:

  nut-upsd:
    container_name: nut-upsd
    image: instantlinux/nut-upsd
    volumes:
    - "/home/pi/nut-upsd-password:/run/secrets/nut-upsd-password"
    environment:
    - "PORT=/dev/bus/usb/001/003"
    - "NAME=tecnoware"
    - "DESCRIPTION=tecnoware"
    - "DRIVER=blazer_ser"
    - "API_USER=nomeutente"
    network_mode: host
    privileged: true
    restart: always

Una volta salvato il file docker-compose.yaml, eseguire il comando:

docker-compose up -d nut-upsd

il quale provvederà a istanziare il container.
Lanciato il comando, attendere il completamente del primo avvio. Ci potrebbe volere un po’: per leggere in tempo reale i log e verificare quindi cosa stia succedendo all’interno del container, eseguire il comando:

docker container logs nut-upsd -f

nel log dovremmo trovare qualcosa come:

0.000000 UPS: tecnoware@localhost (master) (power value 1)
0.000059    debug level is '1'
0.000749    Trying to connect to UPS [tecnoware@localhost]
0.001803    Logged into UPS tecnoware@localhost 

Congratulazioni: NUT è ora operativo.

Verifica

A questo punto verifichiamo che i NUT dialoghino correttamente con l’UPS.
Per farlo entriamo in SH sul container:

docker exec -it nut-upsd sh

Per verificare che l’UPS stia dialogando correttamente con i NUT, eseguire ora il comando:

upsc tecnoware

dove ovviamente “tecnoware” è il nome dell’UPS configurato in precedenza.
L’output dovrebbe riportare lo stato istantaneo dell’UPS:

Init SSL without certificate database
battery.charge: 100
battery.voltage: 13.50
battery.voltage.high: 13.00
battery.voltage.low: 10.40
battery.voltage.nominal: 12.0
device.type: ups
driver.name: blazer_usb
driver.parameter.langid_fix: 0x409
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.synchronous: no
driver.version: 2.7.4
driver.version.internal: 0.12
input.current.nominal: 2.0
input.frequency: 50.1
input.frequency.nominal: 50
input.voltage: 243.5
input.voltage.fault: 243.5
input.voltage.nominal: 230
output.voltage: 243.5
ups.beeper.status: disabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 0
ups.productid: 5161
ups.status: OL
ups.type: offline / line interactive
ups.vendorid: 0665

Al termine, uscire da SH con:

exit

Verifichiamo ora che Raspberry Pi OS si accorga, banalmente, che la corrente sia venuta a mancare.
Mettiamoci quindi in ascolto sui log con:

docker container logs nut-upsd -f

Basterà ora staccare la spina all’UPS per ottenere, dopo pochi istanti, il seguente messaggio sulla riga di comando:

UPS tecnoware@localhost on battery 

il che confermerà che l’UPS è effettivamente sotto monitoraggio da parte del Raspberry Pi.
Tornare infine alla riga comandi premendo CTRL+C.

Esecuzione comandi

Se (e non è detto che sia così) oltre al monitoraggio, l’UPS supporta anche la ricezione di comandi, è possibile visualizzarne l’elenco tramite un comando specifico.

Per eseguirlo, entriamo in SH sul container:

docker exec -it nut-upsd sh

poi eseguiamo il comando:

upscmd -l tecnoware

ovviamente adeguando il nome dell’UPS interrogato (nell’esempio, “tecnoware“).

Nel caso del Tecnoware 1100, i comandi elencati sono:

Instant commands supported on UPS [tecnoware]:

beeper.toggle - Toggle the UPS beeper
load.off - Turn off the load immediately
load.on - Turn on the load immediately
shutdown.return - Turn off the load and return when power is back
shutdown.stayoff - Turn off the load and remain off
shutdown.stop - Stop a shutdown in progress
test.battery.start - Start a battery test
test.battery.start.deep - Start a deep battery test
test.battery.start.quick - Start a quick battery test
test.battery.stop - Stop the battery test

I comandi sono abbastanza auto-esplicativi.
Ipotizziamo di voler attivare/disattivare il cicalino che suona, automaticamente, in assenza di alimentazione. Il comando avrà questa sintassi:

upscmd tecnoware beeper.toggle

verranno richiesti username e password: il primo sarà admin, la password quella impostata in precedenza.

Al termine, uscire da SH con:

exit

Integrazioni

Una volta realizzata la propria installazione e configurazione di Network UPS Tools, tali funzioni possono essere utilizzate, come illustrato, tramite riga di comando oppure tramite integrazione con la propria domotica personale basata su HUB personali, e altro.

In caso si la propria domotica personale sia basata su Home Assistant, la guida per integrare un’installazione NUT (e quindi gli UPS tramite essa gestiti) è questa qui.

   
Telegram News Channel