{"id":16323997,"url":"https://github.com/marcodifrancesco/homeautomation","last_synced_at":"2026-04-07T18:32:26.524Z","repository":{"id":106802956,"uuid":"136651305","full_name":"MarcoDiFrancesco/HomeAutomation","owner":"MarcoDiFrancesco","description":"System to control and update IOT devices remotely via a website","archived":false,"fork":false,"pushed_at":"2020-05-22T09:50:24.000Z","size":1984,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-01-03T16:19:56.904Z","etag":null,"topics":["arduino","c","css","html","javascript","php","shell","sql"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MarcoDiFrancesco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-08T18:06:51.000Z","updated_at":"2021-03-19T11:04:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"dec0caba-64f6-4563-b58c-32a7618532b5","html_url":"https://github.com/MarcoDiFrancesco/HomeAutomation","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/MarcoDiFrancesco/HomeAutomation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcoDiFrancesco%2FHomeAutomation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcoDiFrancesco%2FHomeAutomation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcoDiFrancesco%2FHomeAutomation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcoDiFrancesco%2FHomeAutomation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MarcoDiFrancesco","download_url":"https://codeload.github.com/MarcoDiFrancesco/HomeAutomation/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarcoDiFrancesco%2FHomeAutomation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31524525,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","c","css","html","javascript","php","shell","sql"],"created_at":"2024-10-10T22:56:19.080Z","updated_at":"2026-04-07T18:32:26.502Z","avatar_url":"https://github.com/MarcoDiFrancesco.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Home automation\r\n\r\n## Introduzione\r\n\r\nQuesto progetto, utilizza l'architettutra client-server per la gestione dei sistemi IOT da remoto tramite un sito web.\r\n\r\n# How to implement\r\n\r\nQuesto progetto prevede la gestione della casa domotica tramite un Web Server, sia remoto che locale.\r\nPer l'utilizzo di un server locale si deve utilizzare il programma XAMPP.\r\n\r\nStep per la creazione:\r\n\r\n* Installare [XAMPP](https://www.apachefriends.org/download.html), [Arduino](https://www.arduino.cc/en/Main/Software), [Processing](https://processing.org/download)\r\n* Scaricare il repository e inserire la cartella unzippata `HomeAutomation-master` in `C:\\xampp\\htdocs`\r\n* Aprire XAMPP e avviare `Apache` e `MySQL`\r\n* Cercare nel browser l'indirizzo [`127.0.0.1/HomeAutomation-master/createDatabase.php`](http://127.0.0.1/HomeAutomation-master/createDatabase.php/) per creare il DataBase\r\n* Aprire `CasaDomotica.ino` con il programma Arduino\r\n* Per importare le librerie andare su `File` →  `Prefesences` → `Sketchbook location` e incollare `C:\\xampp\\htdocs\\HomeAutomation-master`\r\n* Caricare il codice nel proprio Arduino con il comando `Upload`\r\n* Aprire il file `processing.pde` → `processing` e avviare il programma con il triangolo `Run`\r\n\r\n## Componenti utilizzati\r\n\r\nIl progetto é incentrato sulla programmazione che porta la casa domotica a comunicare con il sito Web.\r\n\r\nLa comunicazione avviene tramite 5 componenti:\r\n\r\n- Sensori e led\r\n- Arduino\r\n- Raspberry\r\n- Relational DataBase\r\n- Sito Web\r\n\r\n![Component view](assets/images/ComponentsView.png)\r\n\r\nLa comunicazione dei dati tra il sito web e i sensori è bidirezionale. I dati che sono inseriti all’interno del database sono richiesti sia dal sito web, sia da Raspberry che da Arduino.\r\n\r\n## Setup\r\n\r\n### Arduino\r\n\r\n\u003cimg src=\"assets/images/Arduino.jpg\" width=\"200\"\u003e\r\n\r\nLa programmazione di questo microcontrollore avviene tramite l'ambiente di sviluppo integrato: Arduino.  \r\nQuesta applicazione va a prendere i dati dei vari sensori connessi tramite i pin, e va a leggere se i led devono essere accesi o spenti, per poi aggiornarli.\r\n\r\n``` C++\r\n#include \u003cdht11.h\u003e\r\n\r\n#define DHT11_PIN2 A1 // temperature sensor n1\r\n#define DHT11_PIN1 A0 // temperature sensor n2\r\n#define DHTTYPE DHT11\r\ndht11 sensore;\r\n\r\nchar incoming;\r\nint looppp = 8;\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n\r\n  pinMode(8, OUTPUT); // led n1\r\n  pinMode(9, OUTPUT); // led n2\r\n  pinMode(10, OUTPUT); // led n3\r\n  pinMode(11, OUTPUT); // led n4\r\n  pinMode(12, OUTPUT); // led n5\r\n  pinMode(13, OUTPUT); // led n6\r\n}\r\n\r\nvoid loop() {\r\n  //  led(8, 13); // firstPin, lastPin\r\n\r\n  temperatureSensor(1);\r\n  // connection with pin A0\r\n  // print humidity and temperature\r\n\r\n  temperatureSensor(2);\r\n  // connection with pin A1\r\n  // print humidity and temperature\r\n\r\n  Serial.print(analogRead(A2));\r\n  // print light sensor n1\r\n  Serial.print(\"\\t\");\r\n\r\n  Serial.print(analogRead(A3));\r\n  // print light sensor n1\r\n  Serial.print(\"\\t\");\r\n\r\n  Serial.println();\r\n  // print \\n to close the string that will be sent\r\n\r\n  if (Serial.available()) {\r\n    while (Serial.available() \u003e 0) {\r\n      incoming = Serial.read();\r\n\r\n      if (incoming == '1') {\r\n        digitalWrite(looppp, HIGH);\r\n      } else {\r\n        digitalWrite(looppp, LOW);\r\n      }\r\n      if (looppp == 13) {\r\n        looppp = 8;\r\n      } else {\r\n        looppp = looppp + 1;\r\n      }\r\n    }\r\n  }\r\n  delay(1000);\r\n}\r\n\r\nvoid temperatureSensor(int nSensor) {\r\n  if (nSensor == 1) {\r\n    sensore.read(DHT11_PIN1); // read data\r\n  } else if (nSensor == 2) {\r\n    sensore.read(DHT11_PIN2); // read data\r\n  } else {\r\n    Serial.print(\"Error\");\r\n  }\r\n  Serial.print(sensore.humidity, 1);\r\n  // print humidity\r\n  Serial.print(\"\\t\");\r\n\r\n  Serial.print(sensore.temperature, 1);\r\n  // print temperature\r\n  Serial.print(\"\\t\");\r\n}\r\n```\r\n\r\n## Raspberry\r\n\r\nPer la comunicazione seriale con Arduino viene utilizzato Processing, un programma basato su Java. Il programma ha lo scopo di far comunicare Arduino al database. Il programma fa richiesta al database per richiedere quali led devono essere accesi, e passa questi dati all'Arduino, inoltre il programma fa la richiesta ad Arduino dei dati dei sensori per passarli al database.\r\n\r\nIl file scritto in processing è stato salvato in un file all’interno di Raspberry. Questo viene avviato all’accensione del Raspberry tramite uno script. Lo scipt è stato preso dalla [seguente pagina](https://raspberrypi.stackexchange.com/questions/8734/execute-script-on-start-up).\r\n\r\n``` C++\r\nimport processing.serial.*;\r\nSerial port;\r\nString input;\r\n\r\nvoid setup()  {\r\n  port = new Serial(this, Serial.list()[1], 9600); // windows\r\n  // port = new Serial(this, Serial.list()[2], 9600); // raspbian\r\n  delay(5000);\r\n}\r\n\r\nvoid draw() {\r\n  if(port.available()\u003e0){\r\n    input = port.readStringUntil('\\n');\r\n  }\r\n  if(input != null){\r\n    input = trim(input);\r\n    int dataSensors[];\r\n    dataSensors = int(split(input,'\\t'));\r\n    Try{\r\n      // link to pass in POST the data\r\n      loadStrings(\"https://www.marcodifrancesco.com/tesina/insertData.php?data1=\"+dataSensors[0]+\r\n      \"\u0026data2=\"+dataSensors[1]+\"\u0026data3=\"+dataSensors[2]);\r\n    } catch (Exception e) {\r\n      System.out.println(\"Exception occurred\");\r\n    }\r\n  }\r\n\r\n  print(input+\"\\n\");\r\n\r\n  int out[] = new int[7];\r\n  for(int led=1;led\u003c=3;led++){\r\n    // link to get from the query the led state\r\n    String resultQuery[]= loadStrings(\"https://www.marcodifrancesco.com/tesina/checkLed.php?led=\"+led);\r\n    int ledState = Integer.parseInt(resultQuery[0]);\r\n    out[led]=int(ledState);\r\n  }\r\n  String output = str(out[1])+str(out[2])+str(out[3]);\r\n  port.write(output); // testing if works\r\n  delay(1000);\r\n}\r\n\r\n```\r\n\r\n## Database\r\n\r\nI dati dei sensori e dei led vengono salvati all'interno del database relazione. Come DBMS utilizzo MySql. La struttura è organizzata in due tabelle: sensori e led. Tra queste due tabelle non è prevista alcuna relazione.\r\n\r\nLe due tabelle si differenziano per la tipologia di dati in cui vengono inseriti:\r\n\r\n- per la tabella dei sensori sono stati utilizzati `INT` provenienti dai sensori\r\n- per la tabella dei led sono stati utilizzati `TINYINT`, dato che il dato lo stato dei led può variare solamente tra 0 e 1 (spento o acceso)\r\n\r\nTabella dei sensori:\r\n\r\n\u003cimg src='assets/images/Database1.png' width=200\u003e\r\n\r\n``` SQL\r\n`id` INT(8) NOT NULL AUTO_INCREMENT ,\r\n`sensor1` INT(64) NOT NULL ,\r\n`sensor2` INT(64) NOT NULL ,\r\n`sensor3` INT(64) NOT NULL ,\r\nPRIMARY KEY (`id`)\r\n```\r\n\r\nTabella dei LED:\r\n\r\n\u003cimg src='assets/images/Database2.png' width=100\u003e\r\n\r\n``` SQL\r\n`id` INT(8) NOT NULL AUTO_INCREMENT ,\r\n`state` TINYINT(1) NOT NULL ,\r\nPRIMARY KEY (`id`)\r\n```\r\n\r\n## Query\r\n\r\nPer la richiesta dei dati al database sono state utilizzate delle query in SQL inserite all’interno dei file PHP presenti nel sito. Le parentesi graffe presenti all’interno del codice rappresentano i dati che vengono passati tramite PHP.\r\n\r\nLa prima query viene utilizzata dal sito, che richiede questa query in modalità POST (con la libreria di AJAX), nel momento in cui viene aggiornata la pagina HTML. Mentre questa query viene richiamata da Processing in modalità GET, e viene richiesta nel momento in cui viene effettuato il controllo se la luce é stata \"accesa\" o \"spenta\".\r\n\r\n``` SQL\r\nSELECT state FROM led where id={$ledNumber}\r\n\tUPDATE led SET state='{$ledState}' WHERE id={$ledNumber}\r\n```\r\n\r\nPer l’inserimento dei dati dei sensori. Viene richiesta da Raspberry per inserire i dati che vengono passati da Arduino. Questa pagina viene richiamata in modalità POST.\r\n\r\n``` SQL\r\nINSERT INTO sensors(sensor1,sensor2,sensor3)\r\nVALUES ('{$data1}', '{$data2}', '{$data3}');\r\n```\r\n\r\nQuery query viene utilizzata per la richiesta dei valori dei sensori inseriti nel database. La query richiede il valore massimo (`$i` rappresenta il numero del sensore), valore minimo e ultimo valore, per ogni sensore presente all’interno del database. L’ultimo dato presente all’interno del database é stato fatto in JOIN per fare in modo che ORDER BY non andasse a influire nei valori massimi e nei valori minimi.\r\n\r\n``` SQL\r\nSELECT lastTable.sensor{$i} AS lastRecord,\r\nMAX(sensors.sensor{$i}) AS maxRecord,\r\nMIN(sensors.sensor{$i}) AS minRecord\r\n\tFROM sensors\r\n\tJOIN (SELECT id,sensor{$i}\r\n\t\t\tFROM sensors\r\n\t\t\tORDER BY sensors.id DESC\r\n\t\t\tLIMIT 1) lastTable\r\n```\r\n\r\n## Website\r\n\r\nIl sito web utilizzato é stato utilizzato per il progetto é stato creato in HTML utilizzando i fogli di stile CSS. La connessione al sito web può essere fatta utilizzando due siti:  \r\n[marcodifrancesco.com/tesina](https://marcodifrancesco.com/tesina)  \r\nSito è allocato su un web server remoto fornito da un provider.  \r\n[marcodifrancesco.hopto.org/tesina](https://marcodifrancesco.hopto.org/tesina/)  \r\nSito di supporto in caso il primo non sia disponibile.  \r\nIl sito di supporto è stato montato su un computer in cui è installato XAMPP, e viene utilizzato per la gestione dei file (Apache 2) e dei database (MySQL).  \r\nL’IP (assegnato dinamicamente) del computer viene collegato al link (marcodifrancesco.hopto.org) tramite NO-IP.\r\n\r\nLe pagine principali inserite all’interno del sito web sono:\r\n- [index.php](website/index.php)\r\n- [checkLed.php](website/checkLed.php)\r\n- [insert.php](website/insert.php)\r\n- [updateTable.php](website/updateTable.php)\r\n- [insertData.php](website/insertData.php)\r\n\r\n### Index\r\n\r\n`index.php` è la pagina utilizzata per mostrare l’interfaccia dei led e dei sensori.  \r\nL’interfaccia di questa pagina é costituita da una serie di bottoni con cui é possibile interagire, e una tabella che mostra i dati dei sensori.  \r\nI bottoni che rappresentano i led, sono stati implementati con checkbox; lo stile di questi bottoni é importato da W3School.\r\n\r\n``` HTML\r\n\u003cdiv\u003e\r\n    LED 1\r\n    \u003clabel class=\"switch\"\u003e\r\n        \u003cinput type=\"checkbox\" name=\"state\" id=\"1\" value=\"1\" onload=\"updateLed();\"\u003e\r\n        \u003cspan class=\"slider round\"\u003e\u003c/span\u003e\r\n    \u003c/label\u003e\r\n\u003c/div\u003e\r\n\u003cdiv\u003eLED 2\r\n    \u003clabel class=\"switch\"\u003e\r\n        \u003cinput type=\"checkbox\" name=\"state\" id=\"2\" value=\"2\" onload=\"updateLed();\"\u003e\r\n        \u003cspan class=\"slider round\"\u003e\u003c/span\u003e\r\n    \u003c/label\u003e\r\n\u003c/div\u003e\r\n```\r\n\r\nL’aggiornamento in background dei checkbox viene gestito da uno Script, che all’apertura della pagina avvia una funzione che controlla se i checkbox debbano essere spenti (con 0) oppure accesi (con 1). Lo Script inserito utilizza le librerie di Google jQuery AJAX, per implementare i metodi che vengano aggiornati in background.\r\n\r\n### Script (front end)\r\n\r\n``` JavaScript\r\n$(document).ready(function(){\r\n    $('[onload]').each(function updateLed() {\r\n        var ledNumber = $(this).val();\r\n        $.ajax( {\r\n            url: \"check.php\",\r\n            method: \"POST\",\r\n            data: {\r\n                ledNumber: ledNumber\r\n            },\r\n            success: function (ledState) {\r\n                if ( ledState == 0 ) {\r\n                    document.getElementById( ledNumber ).checked = false;\r\n                } else {\r\n                    document.getElementById( ledNumber ).checked = true;\r\n                }\r\n            }\r\n        } );\r\n    } );\r\n} );\r\n```\r\n\r\n### PHP (back end)\r\n\r\n``` PHP\r\n$ledNumber = $_POST[ \"ledNumber\" ];\r\n$query = \"SELECT state FROM led WHERE id={$ledNumber}\";\r\n$sendquery = mysqli_query( $connect, $query );\r\n$takedata = mysqli_fetch_row($sendquery);\r\n$ledState = $takedata[0];\r\necho $ledState;\r\n```\r\n\r\nLa tabella inserita all'interno della pagina contiene tutti i dati dei sensori. Quest’ultima viene interamente creata all’interno della pagina PHP, e vine e stampata all’interno del tag `\u003cdiv\u003e`. Lo script presente dentro la pagina HTML, aggiorna la tabella, una volta al secondo (1000 millisecondi) facendo richiesta alla pagina PHP. La pagina PHP richiede al database i dati dei sensori aggiornati, e passa i dati stampati direttamente dentro una tabella.\r\n\r\n### HTML\r\n\r\n``` HTML\r\n\u003cdiv id=\"tableResult\"\u003e\u003c/div\u003e\r\n```\r\n\r\n### JavaScript (front end)\r\n\r\n``` JavaScript\r\n$(document).ready(function(){\r\n  $('[onload]').each(function updateTable(){\r\n    $.ajax({\r\n      url:\"updateTable.php\",\r\n      success:\r\n      function(tableResult){\r\n        $('#tableResult').html(tableResult);\r\n        setTimeout(function(){\r\n          updateTable();\r\n        },1000); // update every sec\r\n      }\r\n    });\r\n  });\r\n});\r\n```\r\n\r\n### PHP (back end)\r\n\r\n``` PHP\r\necho\"\u003ctable\u003e\r\n      \u003ctr\u003e\r\n        \u003cth\u003e\u003c/th\u003e\r\n        \u003cth\u003eNow\u003c/td\u003e\r\n        \u003cth\u003eMax\u003c/td\u003e\r\n        \u003cth\u003eMin\u003c/td\u003e\r\n      \u003c/tr\u003e\";\r\nfor ($i=1; $i \u003c= 6; $i++) {\r\n      $query = \"\r\n      SELECT lastTable.sensor{$i} AS lastRecord,\r\n      MAX(sensors.sensor{$i}) AS maxRecord,\r\n      MIN(sensors.sensor{$i}) AS minRecord\r\n      FROM sensors\r\n      JOIN (SELECT id,sensor{$i}\r\n          FROM sensors\r\n          ORDER BY sensors.id DESC\r\n          LIMIT 1) lastTable\";\r\n      $resultQuery = mysqli_query($connect, $query);\r\n      $resultRow=mysqli_fetch_assoc($resultQuery);\r\n      if($i == 1){\r\n        $sensorName = \"Living room gas\";\r\n      } else if ($i == 2) {\r\n        $sensorName = \"Kitchen termperature\";\r\n      }\r\n\r\necho \"\u003ctr\u003e\r\n        \u003cth\u003e{$sensorName}\u003c/th\u003e\r\n        \u003ctd\u003e{$resultRow['lastRecord']}\u003c/td\u003e\r\n        \u003ctd\u003e{$resultRow['maxRecord']}\u003c/td\u003e\r\n        \u003ctd\u003e{$resultRow['minRecord']}\u003c/td\u003e\r\n      \u003c/tr\u003e\";\r\n}\r\necho \"\u003c/table\u003e\";\r\n```\r\n\r\nL’aggiornamento dei checkbox onclick, viene gestito da uno Script che viene attivato nel momento in cui viene selezionato un checkbox. Questo controlla il numero del checkbox da cui é stato attivato, lo stato e richiede alla pagina PHP, di aggiornare lo stato di quel led. La pagina PHP crea una query che richiede al database di aggiornare lo stato del led richiesto (0 oppure 1).\r\n\r\n### JavaScript (front end)\r\n\r\n``` JavaScript\r\n$(document).ready( function () {\r\n  $('input[type=\"checkbox\"]').change( function () {\r\n    var ledNumber = $( this ).val();\r\n    if ( this.checked ) {\r\n      var ledState = 1;\r\n    } else {\r\n      var ledState = 0;\r\n    }\r\n    $.ajax( {\r\n      url: \"insert.php\",\r\n      method: \"POST\",\r\n      data: {\r\n        ledState: ledState,\r\n        ledNumber: ledNumber\r\n      },\r\n      success: function(risposta) {\r\n        $('#result').html(\"Update \"+risposta);\r\n      }\r\n    } );\r\n  } );\r\n} );\r\n```\r\n\r\n### PHP (back end)\r\n\r\n``` PHP\r\n$ledNumber = $_POST[ \"ledNumber\" ];\r\n$query = \"SELECT state FROM led WHERE id={$ledNumber}\";\r\n$sendquery = mysqli_query( $connect, $query );\r\n$takedata = mysqli_fetch_row($sendquery);\r\n$ledState = $takedata[0];\r\necho $ledState;\r\n```\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcodifrancesco%2Fhomeautomation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcodifrancesco%2Fhomeautomation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcodifrancesco%2Fhomeautomation/lists"}