Architettura del sistema di antifurto open-source

Progettare un sistema di antifurto affidabile non significa solo collegare sensori e attuatori, ma definire un’architettura solida, capace di funzionare nel tempo, resistere ai disturbi e gestire errori reali.

Questo progetto nasce con l’obiettivo di realizzare un sistema di sicurezza domestico modulare, basato su:

  • un nodo centrale con Raspberry Pi e Node-RED
  • nodi periferici basati su schede Arduino custom
  • una comunicazione cablate RS485, robusta e scalabile

In questo articolo vediamo la visione d’insieme del sistema, senza entrare ancora nei dettagli di scheda, firmware o flussi software.

Obiettivi del progetto

Prima di entrare nell’architettura, è importante chiarire cosa questo sistema vuole (e non vuole) essere.

Obiettivi principali

  • Affidabilità nel tempo
  • Resistenza ai disturbi elettrici
  • Modularità (aggiungere o rimuovere nodi)
  • Separazione netta tra:
  • logica di alto livello
  • gestione hardware di basso livello

Cosa non è

  • Un prodotto commerciale “chiavi in mano”
  • Un antifurto wireless basato su cloud
  • Un sistema chiuso o proprietario

Il progetto è open-source e nasce come piattaforma di studio, sperimentazione e possibile base evolutiva.

Panoramica generale dell’architettura

Il sistema è suddiviso in tre livelli principali:

  • Nodo centrale
  • Rete di comunicazione
  • Nodi periferici

Questa separazione è fondamentale per mantenere il sistema leggibile, manutenibile ed estendibile.

Nodo centrale: Raspberry Pi + Node-RED

Il nodo centrale è basato su Raspberry Pi, che svolge il ruolo di cervello del sistema.

Il Raspberry:

  • raccoglie i dati dai nodi periferici
  • gestisce la logica dell’antifurto
  • mantiene lo stato globale del sistema
  • gestisce notifiche, log ed eventuali interfacce utente

Il tutto è orchestrato tramite Node-RED, che permette di:

  • isualizzare chiaramente i flussi logici
  • modificare il comportamento senza ricompilare codice embedded
  • debuggare facilmente eventi e stati

L’utilizzo di una piattaforma supportata dalla Raspberry Pi Foundation garantisce:

  • stabilità software
  • grande disponibilità di librerie
  • lunga vita del progetto

Nodi periferici: schede Arduino dedicate

I nodi periferici sono basati su schede Arduino custom, progettate specificamente per questo sistema.

Ogni nodo è pensato per:

  • gestire sensori locali
  • comandare attuatori (come le tapparelle)
  • comunicare con il nodo centrale
  • continuare a funzionare correttamente anche in caso di problemi di rete

Ogni scheda può gestire:

  • 2 sensori IR (interno ed esterno)
  • sensore magnetico finestra
  • pulsanti su / giù tapparella
  • sensori di stato tapparella

La logica di basso livello (lettura sensori, debounce, sicurezza locale) è sempre demandata al nodo Arduino, non al Raspberry.

Comunicazione: perché RS485

Uno degli aspetti chiave del progetto è la scelta della comunicazione RS485.

Perché RS485 in un antifurto

  • Comunicazione cablata, quindi più sicura
  • Elevata immunità ai disturbi
  • Lunghe distanze (decine o centinaia di metri)
  • Possibilità di collegare più nodi sullo stesso bus

A differenza di soluzioni Wi-Fi o radio:

  • non dipende dalla qualità del segnale
  • non introduce latenze imprevedibili
  • non richiede cloud o servizi esterni

La rete è organizzata in modalità master / slave, con il Raspberry come master e le schede Arduino come slave indirizzati.

Separazione delle responsabilità

Un principio fondamentale di questo progetto è la separazione dei compiti:

LivelloResponsabilità
Raspberry + Node-REDLogica globale, stati, notifiche
RS485Trasporto affidabile dei dati
ArduinoGestione hardware e sicurezza locale

Questa separazione:

  • riduce la complessità
  • migliora l’affidabilità
  • rende il sistema più facile da espandere

Scalabilità del sistema

L’architettura è pensata per crescere:

  • aggiungere nuove schede senza modificare l’impianto esistente
  • estendere il protocollo di comunicazione
  • integrare nuovi tipi di sensori
  • separare zone e funzioni

Ogni nodo è indipendente e identificato in modo univoco sulla rete RS485.

Conclusione

Questa architettura rappresenta la base di tutto il progetto.
Nei prossimi articoli entreremo nel dettaglio di:

  • scheda elettronica
  • scelte hardware
  • firmware Arduino
  • protocollo RS485
  • flussi Node-RED

Perché ho progettato questa scheda elettronica

Questa scheda elettronica nasce come progetto personale di studio e sperimentazione, con l’obiettivo di analizzare e mettere in pratica alcune scelte progettuali tipiche dei sistemi di controllo e sicurezza.

Non si tratta di un prodotto commerciale, ma di una base di lavoro tecnica pensata per test, valutazioni e approfondimenti su architettura, comunicazione e affidabilità.

Obiettivo del progetto

L’idea di partenza era realizzare una scheda flessibile, facilmente modificabile e adatta a diversi scenari di prova.

In particolare, gli obiettivi principali sono:

  • gestire ingressi e uscite digitali
  • comunicare tramite bus seriale RS485
  • separare correttamente la logica di controllo dalla parte di campo
  • rendere il sistema semplice da analizzare e debuggare

Architettura generale della scheda

Uno degli aspetti più importanti del progetto è l’architettura a blocchi.

La scheda è suddivisa concettualmente in tre sezioni principali:

  1. Alimentazione
  2. Logica di controllo
  3. Interfaccia verso il campo

Questa separazione non è casuale:
serve a ridurre i disturbi, migliorare l’affidabilità e semplificare l’individuazione dei problemi durante i test.

Logica di controllo

La logica di controllo è il “cuore” della scheda.
Qui risiedono:

  • il microcontrollore
  • la gestione del firmware
  • la logica di comunicazione

La scelta è ricaduta su una soluzione semplice e facilmente programmabile, adatta a sperimentazioni rapide e modifiche frequenti.

Perché RS485

La comunicazione tra la scheda e il resto del sistema avviene tramite RS485.

La scelta di questo bus è motivata da alcune caratteristiche fondamentali:

  • robustezza
  • buona immunità ai disturbi
  • utilizzo diffuso in ambito industriale
  • adatto a sistemi distribuiti

RS485 rappresenta un ottimo compromesso tra semplicità e affidabilità, soprattutto in ambienti elettricamente “rumorosi”.

Affidabilità e protezioni

Anche in un progetto di studio è importante considerare cosa succede in condizioni non ideali.

Per questo motivo, nella progettazione sono stati considerati aspetti come:

  • protezioni sugli ingressi
  • filtraggio dei segnali
  • separazione delle masse
  • gestione degli errori di comunicazione

Molti problemi emergono solo durante i test reali, ed è proprio questo uno degli obiettivi principali del progetto.

Prossimi approfondimenti

Questo articolo introduce la scheda a livello generale.
Nei prossimi approfondimenti verranno analizzati nel dettaglio:

  • l’alimentazione e le scelte progettuali
  • la gestione degli ingressi digitali
  • la comunicazione RS485 e le terminazioni
  • le criticità emerse durante i test
  • cosa migliorare in una futura revisione

Nota importante

Questo progetto e i contenuti pubblicati hanno finalità esclusivamente divulgative e di studio.
Non costituiscono attività di installazione, vendita o manutenzione di impianti.

Organizzare le foto in automatico con Python: come ho creato il mio Photo Organizer

Se sei come me, ogni volta che torni da un viaggio o da un evento speciale ti ritrovi con decine (o centinaia!) di foto sparse ovunque: sulla SD della fotocamera, sul telefono, magari anche sul cloud… E poi rimandiamo sempre il momento di organizzarle, finendo in un caos totale.

Ecco perché ho deciso di creare un piccolo programma Python che potesse fare tutto il lavoro sporco per me. Oggi ti presento il mio Photo Organizer, uno script che ordina automaticamente immagini, video e file RAW, dividendo tutto per anno e mese

Come funziona?

Il funzionamento è semplice:

  1. Gli dici dove si trovano i tuoi file (ad esempio la scheda SD della fotocamera).
  2. Gli dici dove vuoi che vengano salvati (un hard disk, una cartella sul PC…).
  3. Il programma analizza ogni file e lo sposta nella cartella giusta, basandosi sulla data di creazione.

Ad esempio, una foto scattata il 10 agosto 2023 finirà in:

/Tuodisco/JPG/2023/10-Agosto/nomedelfile.jpg

Lo script riconosce automaticamente:

  • Foto classiche (.jpg, .png, ecc.)
  • Video (.mp4, .mov, ecc.)
  • Immagini RAW da fotocamere professionali (.nef, .cr2…)

E se un file è già presente, non lo ricopia. Tutto è documentato in un file di log!

Un’occhiata al codice (semplificata!)

Ecco un pezzetto chiave del codice che decide dove mettere ogni file:

def get_dest_path(cfile, HD, file):
   datafile = 
datetime.datetime.fromtimestamp(os.path.getmtime(cfile))
   Anno = HD + datafile.strftime("%Y")
   GiornoMese = Anno + "/" + datafile.strftime("%d") + "-" + 
   mesi[int(datafile.strftime("%m"))-1]
   return os.path.join(GiornoMese, file)

In pratica, prende la data di modifica del file, la trasforma in anno/mese/giorno, e costruisce il percorso finale dove copiare il file.

Perché ho usato Python?

Python è uno dei linguaggi più semplici e versatili: perfetto per chi vuole automatizzare attività ripetitive senza impazzire. Inoltre, grazie a librerie come os, shutil e tqdm, possiamo:

  • Cercare file dentro cartelle e sottocartelle
  • Copiarli in modo sicuro
  • Visualizzare il progresso dell’operazione

Come usarlo?

python Photo-Organizer.py /percorso/della/SD /percorso/dell/harddisk/

E voilà, il tuo archivio fotografico è pronto!

Vuoi provarlo anche tu?

Questo tipo di script è perfetto per chi vuole iniziare con l’automazione in Python. Se vuoi provare anche tu, scrivimi e sarò felice di condividere lo script o aiutarti a personalizzarlo!

import os
import datetime
import shutil
import sys
import logging
from tqdm import tqdm

# Configura il logging
logging.basicConfig(
    filename='photo_organizer.log',  # Nome del file di log
    level=logging.INFO,  # Impostiamo il livello di log (INFO, DEBUG, ERROR, etc.)
    format='%(asctime)s - %(levelname)s - %(message)s',  # Formato del log
)

mesi = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]

img = (".jpg", ".jpeg", ".jfif", ".pjpeg", ".pjp", ".png", ".gif", ".webp", ".svg", ".apng", ".avif")

video = (".webm", ".mts", ".m2ts", ".TS", ".mov", ".mp4", ".m4p", ".m4v", ".mxf")

imgraw = (".nef", ".cr2", ".cr3")

def main():
    if len(sys.argv) < 3:
        print_help()
        sys.exit(1)

    SD = sys.argv[1]
    HardDisk = sys.argv[2]    
    logging.info(f"Percorso SD: {SD}")
    logging.info(f"Percorso HD: {HardDisk}")

    JPG = HardDisk + "JPG/"
    RAW = HardDisk + "RAW/"
    VIDEO = HardDisk + "VIDEO/"

    NumJPGCopiati = 0
    NumJPGNonCopiati = 0
    NumRAWCopiati = 0
    NumRAWNonCopiati = 0
    NumVIDEOCopiati = 0
    NumVIDEONonCopiati = 0
    NumFileEstSbagliata = 0
    NumFileNonCopiati = 0
    file_list = []
    
    for root, dirs, files in os.walk(SD):
        for file in files:
            file_list.append((root, file))

    for root, file in tqdm(file_list, desc="Copia file", unit="file"):
        if is_image(file):
            if copia_file(JPG, root, file):
                NumJPGCopiati += 1
            else:
                NumJPGNonCopiati += 1
        elif is_raw(file):
            if copia_file(RAW, root, file):
                NumRAWCopiati += 1
            else:
                NumRAWNonCopiati += 1
        elif is_video(file):
            if copia_file(VIDEO, root, file):
                NumVIDEOCopiati += 1
            else:
                NumVIDEONonCopiati += 1
        else:
            logging.warning(f"{file} - Estensione Sbagliata")
            NumFileEstSbagliata += 1

    logging.info(f"Numero JPG COPIATI = {NumJPGCopiati}")
    logging.info(f"Numero JPG Non COPIATI = {NumJPGNonCopiati}")
    logging.info(f"Numero RAW COPIATI = {NumRAWCopiati}")
    logging.info(f"Numero RAW Non COPIATI = {NumRAWNonCopiati}")
    logging.info(f"Numero VIDEO COPIATI = {NumVIDEOCopiati}")
    logging.info(f"Numero VIDEO Non COPIATI = {NumVIDEONonCopiati}")
    logging.info(f"Numero Estensione Sbagliata = {NumFileEstSbagliata}")
    
    TotaleCopiati = NumJPGCopiati + NumRAWCopiati + NumVIDEOCopiati
    TotaleNonCopiati = NumJPGNonCopiati + NumRAWNonCopiati + NumVIDEONonCopiati + NumFileEstSbagliata
    
    logging.info(f"Numero FILE Copiati Totali = {TotaleCopiati}")
    logging.info(f"Numero FILE Non Copiati Totali = {TotaleNonCopiati}")
    logging.info(f"Numero FILE Totali = {TotaleCopiati + TotaleNonCopiati}")

def print_help():
    print("Utilizzo:")
    print("  python Photo-Organizer.py <PERCORSO_SORGENTE> <PERCORSO_DESTINAZIONE> ...")
    print("Esempio:")
    print("  python Photo-Organizer.py /media/davide/NIKON D500/DCIM/115ND500/ /home/davide/Immagini/")
    print("\nDescrizione:")
    print("  Questo script accetta due argomenti e copia ")
    print("  immagini (.jpg, .jpeg, .jfif, .pjpeg, .pjp, .png, .gif, .webp, .svg, .apng, .avif)")
    print("  video (.webm, .mts, .m2ts, .TS, .mov, .mp4, .m4p, .m4v, .mxf)")
    print("  immagini RAW (.nef,.cr2,.cr3)")
    print("  Se non inserisci argomenti, mostra questo messaggio di aiuto.")

def get_dest_path(cfile, HD, file):
    datafile = datetime.datetime.fromtimestamp(os.path.getmtime(cfile))
    Anno = HD + datafile.strftime("%Y")
    GiornoMese = Anno + "/" + datafile.strftime("%d") + "-" + mesi[int(datafile.strftime("%m"))-1]
    return os.path.join(GiornoMese, file)

def is_image(file):
    return os.path.splitext(file)[1].lower() in img

def is_raw(file):
    return os.path.splitext(file)[1].lower() in imgraw

def is_video(file):
    return os.path.splitext(file)[1].lower() in video

def copia_file(HD, root, file):
    cfile = os.path.join(root, file)
    dest_path = get_dest_path(cfile, HD, file)
    if os.path.exists(dest_path):
        logging.info(f"{file} - Già Esistente.")
        return False
    else:
        os.makedirs(os.path.dirname(dest_path), exist_ok=True)
        shutil.copyfile(cfile, dest_path)
        logging.info(f"{file} - Copiato con successo in {dest_path}")
        return True

if __name__ == "__main__":
    main()

Spieghiamo i nodi di Node-RED

Node-RED è uno strumento di programmazione per collegare insieme dispositivi hardware, API e servizi online. Fornisce un editor basato su browser che semplifica il collegamento dei flussi utilizzando l’ampia gamma di nodi che può essere distribuita al runtime con un solo clic.

I nodi sono la parte fondamentale di Node-RED, iniziamo con i due che si usano più di tutti, l’iniect e il debug

questi due nodi servono a provare il codice l’iniect attraverso il timestamp ovvero i secondi della macchina in cui è installato e il debug che permette di visualizzare il risultato dei nodi precedenti nella barra di sinistra. L’iniect in particolare può anche impostare un uscita temporizzata che può comandare i nodi successivi.

REMOTE RED SU DIETPI

Con Remote-RED puoi accedere alla dashboard di Node-RED direttamente dal cellulare anche se non sei a casa. Puoi anche farti inviare notifiche da Node-RED. Le notifiche possono avere anche azioni a cui puoi rispondere direttamente.

Purtroppo su Dietpi non funziona perchè Remote-REDcomunica con il server attraverso SSH Client, Dietpi per default non ha nessun SSH Client. installarlo è semplice, basta aprire il software di dietpi con questo comando:

sudo apt install openvpn

VirtualBox Con NodeRed

Per poter sviluppare progetti con raspberry e con Node red, possiamo utilizzare una macchina virtuale con VirtualBox. oggi vi spiego come installare Dietpi e Node red su virtual box. Utilizzare una macchina virtuale per sviluppare il tutto è ottimo per poter testare i nostri programmi.

Sul sito Oracle VM VirtualBox possiamo scaricare l’ultima versione per il nostro sistema operativo.

Quando lo abbiamo installato possiamo scaricare l’immagine del sistema operativo Dietpi.

DietPi-VirtualBox-download-image

Una volta scaricato il SO, lo scompattiamo e importiamo l’applicazione virtuale

Lasciamo tutto invariato e clicchiamo su Importa, ci ritroveremo con una riga così:

Ora se avviamo il SO avremo un errore perchè non abbiamo installato l’Extension Pack lo scarichiamo da qui

Cliccandoci semplicemente sopra lo possiamo installare:

Accettiamo e si installa l’extension pack. Ora possiamo riavviare e aspettare che finisce di riavviarsi il sistema operativo.

quando si presenta questa schermata premere cancel per non cambiare la password di default. ora possiamo installare NodeRed, sul terminale digitiamo:

dietpi-config

uscirà questa maschera

selezionare Browse Software nell’elenco dovremo ricercare Node Red, vedi sotto:

ora possiamo selezionare Ok e Install nella schermata precedente. quando ha finito di installare possiamo riavviare il sistema e controllare l’indirizzo IP:

digitiamo indirizzoIP:1880 sul browser del PC come ad esempio questo:

192.168.1.49:1880

e avremo il sistema Node Red direttamente sul PC

questo è tutto, grazie per la lettura

Node-RED

Oggi parliamo di Node-RED,il sito ufficiale é: www.nodered.org/ ed è un potente strumento per la creazione di applicazioni Internet of Things (IoT) con l’obiettivo di semplificare il “collegamento” dei blocchi di codice per eseguire le attività. Utilizza un approccio di programmazione visuale che consente agli sviluppatori di collegare blocchi di codice predefiniti, noti come “nodi”, insieme per eseguire un’attività. I nodi collegati, solitamente con una combinazione di nodi di input, nodi di elaborazione e nodi di output, quando cablati insieme, costituiscono un “flusso”.

Originariamente sviluppato come progetto open source presso IBM alla fine del 2013, per soddisfare la necessità di collegare rapidamente hardware e dispositivi a servizi Web e altri software – come una sorta di colla per l’IoT – si è rapidamente evoluto fino a diventare una programmazione IoT per scopi generali attrezzo. È importante sottolineare che Node-RED ha rapidamente sviluppato una base di utenti significativa e in crescita e una comunità di sviluppatori attivi che stanno contribuendo con nuovi nodi che consentono ai programmatori di riutilizzare il codice Node-RED per un’ampia varietà di attività.

Sebbene Node-RED fosse originariamente progettato per funzionare con l’Internet of Things, ovvero dispositivi che interagiscono e controllano il mondo reale, man mano che si è evoluto, è diventato utile per una vasta gamma di applicazioni.

Installare e aggiornare Node-RED

il sito di Node-RED ha già scritto uno script per installare automaticamente Node-RED su Raspberry. Questo script lo aggiorna anche quando è già installato.

Basta copiare il codice aprire un terminale su Raspberry e copiarci dentro questa stringa:

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

Per funzionare hai bisogno di curl, se non è installato su raspberry perché ad esempio hai installato dietpi possiamo installarlo attraverso il terminale con questo codice:

sudo apt install build-essential git curl