{"id":16,"date":"2015-02-05T15:17:47","date_gmt":"2015-02-05T14:17:47","guid":{"rendered":"http:\/\/www.prioprio.it\/wordpress\/?p=16"},"modified":"2015-02-05T21:10:34","modified_gmt":"2015-02-05T20:10:34","slug":"basduino","status":"publish","type":"post","link":"https:\/\/www.prioprio.it\/wordpress\/basduino\/","title":{"rendered":"basduino: Arduino yun come display arrivi per gli autobus romani"},"content":{"rendered":"<p>&nbsp;<\/p>\n<p class=\"normal\" style=\"text-align: justify;\"><a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-17\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/1-294x300.jpg\" alt=\"Totem\" width=\"294\" height=\"300\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/1-294x300.jpg 294w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/1.jpg 432w\" sizes=\"auto, (max-width: 294px) 100vw, 294px\" \/><\/a>Era da tempo che cercavo un progettino sul quale cimentarmi con il mio <a href=\"http:\/\/arduino.cc\/en\/Main\/ArduinoBoardYun?from=Products.ArduinoYUN\">arduino yun<\/a>, uno di quelli che mi impegnasse almeno pi\u00f9 di un giorno, quando, camminando per Roma, mi sono imbattuto in uno di questi pannelli. L\u2019<a href=\"http:\/\/www.atac.roma.it\/\">Atac<\/a> che \u00e8 l\u2019agenzia della mobilit\u00e0 romana, ha da qualche tempo installato alcuni di questi pannelli in giro per la citt\u00e0. La loro funzione (usando il condizionale) sarebbe quella di informare gli utenti di bus e tram degli orari di arrivo per una determinata fermata o banchina. Una cosa molto utile soprattutto per i turisti che, magari, non possono usare le utili applicazioni per smartphone che come il pannello forniscono le stesse informazioni. Fra le varie applicazioni e servizi che offrono questo tipo di informazioni c\u2019\u00e8 il sito: <a href=\"http:\/\/muovi.roma.it\/\">muovi.roma<\/a> , che non \u00e8 altro che una versione pi\u00f9 accessibile del sito Atac. Fra i vari link presenti su quella pagina non mi sono fatto sfuggire questo: <a href=\"http:\/\/muovi.roma.it\/\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-19 size-full\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/2.png\" alt=\"Atac Mobile\" width=\"720\" height=\"82\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/2.png 720w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/2-300x34.png 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a>Che mi ha portato alla pagina del progetto <a href=\"http:\/\/www.agenziamobilita.roma.it\/it\/progetti\/open-data\/\"><span style=\"color: #0563c1;\">Atac Open Data<\/span><\/a><span style=\"text-decoration: underline;\"><span style=\"color: #0563c1;\">.<\/span><\/span> Con Enorme Sorpresa ho quindi scoperto che l\u2019Atac ha realizzato una serie di strumenti ed <a href=\"http:\/\/it.wikipedia.org\/wiki\/Application_programming_interface\"><span style=\"color: #0563c1;\">api<\/span><\/a>, completamente gratuite ed <a href=\"http:\/\/it.wikipedia.org\/wiki\/Open_source\"><span style=\"color: #0563c1;\">open source<\/span><\/a><span style=\"text-decoration: underline;\"><span style=\"color: #0563c1;\">,<\/span><\/span> per interfacciarsi con il sistema di trasporto romano.<\/p>\n<p class=\"normal\" style=\"text-align: justify;\">Navigando sul sito del progetto e spulciando fra la documentazione delle varie api, ho trovato quello che faceva al caso mio: l\u2019api \u201c <a href=\"http:\/\/dev.muovi.roma.it\/muoversi-a-roma\/wiki\/paline.Previsioni\"><span style=\"color: #0563c1;\">paline.Previsioni<\/span><\/a> \u201d con relativo <a href=\"http:\/\/dev.muovi.roma.it\/muoversi-a-roma\/wiki\/Esempio%20di%20utilizzo%20delle%20API%20in%20Python\"><span style=\"color: #0563c1;\">esempio di utilizzo<\/span><\/a>. Questa non fa altro che prendere in input un numero palina (La fermata che volete monitorare) e restituire una <a href=\"http:\/\/it.wikipedia.org\/wiki\/Struttura_dati\"><span style=\"color: #0563c1;\">struttura dati<\/span><\/a> contenente gli arrivi e la lista delle linee che passano per quella fermata, o palina. Avendo quindi trovato il dove (prendere le previsioni), non restava altro che pensare al come.<\/p>\n<p style=\"text-align: center;\"><strong>L\u2019architettura:<a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/schema.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-22\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/schema.png\" alt=\"Schema\" width=\"571\" height=\"455\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/schema.png 571w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/schema-300x239.png 300w\" sizes=\"auto, (max-width: 571px) 100vw, 571px\" \/><\/a><\/strong><\/p>\n<ul>\n<li style=\"text-align: justify;\">Uno script python raccoglie le previsioni grazie all\u2019uso delle api Open Data scrivendole in un file;<\/li>\n<li style=\"text-align: justify;\">Un demone linux:\n<ol>\n<li>Controlla lo script avviandolo a tempo e inizializzandolo con i valori contenuti in un file d\u2019impostazioni;<\/li>\n<li>Logga l\u2019attivit\u00e0 dello script python;<\/li>\n<\/ol>\n<\/li>\n<li style=\"text-align: justify;\">Un\u2019interfaccia php permette:\n<ol>\n<li>L\u2019avvio e l\u2019arresto del demone;<\/li>\n<li>Il cambio palina o fermata, salvando i parametri nel file di configurazione e, se necessario, permette di riavviare il demone;<\/li>\n<li>Letture ed eliminazione del file di log;<\/li>\n<\/ol>\n<\/li>\n<li style=\"text-align: justify;\">Il software Arduino che legge il file creato dallo script python, e lo scrive nel display paginandolo;<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><strong>L\u2019Hardware:<\/strong><\/p>\n<ul>\n<li style=\"text-align: justify;\">Un Arduino yun;<\/li>\n<li style=\"text-align: justify;\">Un alimentatore usb;<\/li>\n<li style=\"text-align: justify;\">Una scheda micro sd;<\/li>\n<li style=\"text-align: justify;\">Un display LCD (quello che uso io \u00e8 di tipo seriale 4&#215;20);<\/li>\n<li style=\"text-align: justify;\">Jumper o cavi dupont per i collegamenti elettrici;<\/li>\n<li style=\"text-align: justify;\">Una connessione internet per il download dei dati;<\/li>\n<li style=\"text-align: justify;\"><a title=\"basduino v0.1\" href=\"http:\/\/www.prioprio.it\/wordpress\/download\/basduino-v0-1\/\" target=\"_blank\">Il codice sorgente che potete scaricare da qui;<\/a><\/li>\n<\/ul>\n<p><strong>Preparativi:<\/strong><\/p>\n<p>Prima di cominciare a smanettare con il codice, se non l\u2019avete gi\u00e0 fatto vi consiglio di fare un paio di cose al vostro yun:<\/p>\n<ul>\n<li>Aumentare lo spazio di memorizzazione inserendo la scheda micro sd, seguendo il <a href=\"http:\/\/arduino.cc\/en\/Tutorial\/ExpandingYunDiskSpace\">tutorial<\/a> presente sul sito di Arduino.<\/li>\n<li>Aggiornare Linino all\u2019ultima versione disponibile seguendo questo <a href=\"http:\/\/arduino.cc\/en\/Tutorial\/YunSysupgrade\">tutorial<\/a> sempre presente sul sito di Arduino.<\/li>\n<\/ul>\n<p class=\"normal\" style=\"text-align: justify;\">Ancora pi\u00f9 importante \u00e8 avere un ambiente di lavoro il pi\u00f9 produttivo possibile, che vi permetta di scrivere il codice nel migliore dei modi. Dato che yun \u00e8 sprovvisto di un\u2019interfaccia grafica, il pi\u00f9 classico dei modi per il mondo Unix\/Linux \u00e8 l\u2019uso di un text editor come <a href=\"http:\/\/it.wikipedia.org\/wiki\/Vi_%28software%29\"><span style=\"color: #0563c1;\">VI<\/span><\/a> o <a href=\"http:\/\/it.wikipedia.org\/wiki\/Nano_%28editor%29\"><span style=\"color: #0563c1;\">nano<\/span><\/a>. Fra i due, quello che uso da anni \u00e8 nano, che per qualche arcano motivo sullo yun non voleva partire, fino a quando non ho aggiunto al sistema questa variabile d\u2019ambiente con il comando:<\/p>\n<blockquote><p><em>echo \u201cexport TERM=xterm\u201d &gt;&gt; \/etc\/profile.<\/em><\/p><\/blockquote>\n<p class=\"normal\" style=\"text-align: justify;\">Fatto ci\u00f2, c\u2019\u00e8 da dire che fa comodo avere un editor testuale da usare direttamente nella shell ma nel 2015 ci sono altre possibilit\u00e0, come ad esempio la condivisione dei file con un computer dove \u00e8 installato un editor di testo grafico(che magari abbia funzioni pi\u00f9 avanzate di quelle di nano e VI). Tra i protocolli di condivisione file pi\u00f9 usati ci sono <a href=\"http:\/\/it.wikipedia.org\/wiki\/Network_File_System\"><span style=\"color: #0563c1;\">NFS<\/span><\/a>; <a href=\"http:\/\/it.wikipedia.org\/wiki\/Secure_copy\"><span style=\"color: #0563c1;\">SFTP\/SCP<\/span><\/a> e <a href=\"http:\/\/it.wikipedia.org\/wiki\/Samba_%28software%29\"><span style=\"color: #0563c1;\">Samba<\/span><\/a><span style=\"text-decoration: underline;\"><span style=\"color: #0563c1;\">,<\/span><\/span> ma forse quello pi\u00f9 utilizzato \u00e8 <a href=\"http:\/\/it.wikipedia.org\/wiki\/Samba_%28software%29\"><span style=\"color: #0563c1;\">Samba<\/span><\/a>, che non \u00e8 altro che l\u2019implementazione Open Source della condivisione file di Windows. Installandolo sul vostro Yun potrete accedere e modificare i file del vostro Arduino Yun direttamente sul vostro pc, sia esso Linux, Windows o Mac. Se vi interessa potete dare uno sguardo a questo breve <a href=\"http:\/\/forum.arduino.cc\/index.php?topic=221286.0\"><span style=\"color: #0563c1;\">tutorial<\/span><\/a>.<\/p>\n<p><strong>Lo script python:<\/strong><\/p>\n<p>Bene, siamo quasi pronti per la nostra prima richiesta che, come detto in precedenza, far\u00e0 uso del codice fornito nell\u2019<a href=\"http:\/\/dev.muovi.roma.it\/muoversi-a-roma\/wiki\/Esempio%20di%20utilizzo%20delle%20API%20in%20Python\">esempio<\/a> presente sul sito open bus. Ma prima di ci\u00f2 parliamo di un paio di cose:<\/p>\n<ul>\n<li>La prima \u00e8 che queste api sono state realizzate in <a href=\"http:\/\/it.wikipedia.org\/wiki\/Python\">python<\/a>, un linguaggio di programmazione molto in voga negli ultimi anni che, con grande semplicit\u00e0, permette di realizzare qualsiasi tipo di applicazione o script. Python \u00e8 disponibile gratuitamente per tutte le maggiori piattaforme e fra queste c\u2019\u00e8 proprio Linux che nel nostro caso \u00e8 nella variate(distribuzione) <a href=\"http:\/\/arduino.cc\/en\/Guide\/ArduinoYun#toc2\">Linino<\/a>\/<a href=\"https:\/\/openwrt.org\/\">Openwrt<\/a> il sistema operativo dell\u2019Arduino yun.<\/li>\n<li>La seconda cosa da sapere \u00e8 che come protocollo di trasmissione delle informazioni viene usato <a href=\"http:\/\/en.wikipedia.org\/wiki\/XML-RPC\">XML-RPC<\/a> , un protocollo che vi permette di effettuare chiamate a procedure che sono su un <a href=\"http:\/\/it.wikipedia.org\/wiki\/Server_web\">web server<\/a> remoto.<\/li>\n<\/ul>\n<p class=\"normal\" style=\"text-align: justify;\">Detto ci\u00f2, passiamo ai fatti. Atac fornisce un semplice <a href=\"http:\/\/dev.muovi.roma.it\/muoversi-a-roma\/wiki\/Esempio%20di%20utilizzo%20delle%20API%20in%20Python\"><span style=\"color: #0563c1;\">esempio di utilizzo delle api<\/span><\/a>, ma se non avete mai sentito parlare di python vi consiglio di leggere o guardare uno dei tantissimi tutorial che affollano la rete, cos\u00ec da avere un\u2019infarinatura generale. Per accedere alle api bisogna prima <a href=\"http:\/\/www.agenziamobilita.roma.it\/it\/progetti\/open-data\/api-real-time.html\"><span style=\"color: #0563c1;\">registrarsi<\/span><\/a> come indicato nella pagina del progetto Open Data, dopo questa formalit\u00e0 si \u00e8 pronti per cominciare creando il primo script python:<\/p>\n<p class=\"normal\" style=\"text-align: justify;\"><a href=\"http:\/\/dev.muovi.roma.it\/muoversi-a-roma\/wiki\/Esempio%20di%20utilizzo%20delle%20API%20in%20Python\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-28\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/3-1024x742.png\" alt=\"Esempio python\" width=\"640\" height=\"464\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/3-1024x742.png 1024w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/3-300x217.png 300w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/3.png 1059w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Una volta creato il file e, dopo aver inserito la chiave ottenuta dal modulo di registrazione, baster\u00e0 digitare \u201c<em>python nomefile.py<\/em>\u201d per avviare lo script appena creato. Come output avremo il \u201c<em>pprint<\/em>\u201d della risposta, ma cos\u2019\u00e8 \u201c<a href=\"https:\/\/docs.python.org\/2\/library\/pprint.html\">pprint<\/a>\u201d ? E\u2019 un modulo python usato per \u201cstampare\u201d il contenuto di una struttura dati in maniera pi\u00f9 accattivante. Se la risposta fosse troppo grande da essere visualizzata nel vostro terminale, potete effettuare un <a href=\"http:\/\/tldp.org\/HOWTO\/Bash-Prog-Intro-HOWTO-3.html\">redirect<\/a> verso un file con: \u201c<em>python nomefile.py &gt; output.txt<\/em>\u201d: in questa maniera l\u2019output del vostro script python viene scritto in un file di testo chiamato \u201coutput.txt\u201d.<\/p>\n<p><a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-31\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/4.png\" alt=\"Output prova\" width=\"912\" height=\"637\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/4.png 912w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/4-300x210.png 300w\" sizes=\"auto, (max-width: 912px) 100vw, 912px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Analizzando il contenuto della risposta, troveremo le previsioni di arrivo per la nostra palina nel formato descritto nella pagina di <a href=\"http:\/\/dev.muovi.roma.it\/muoversi-a-roma\/wiki\/paline.Previsioni\">documentazione dell\u2019api<\/a>, ma come avete potuto vedere l\u2019output contiene una rappresentazione degli arrivi che non pu\u00f2 essere ancora utilizzata per il nostro scopo. Abbiamo quindi bisogno di selezionare e formattare quello che ci interessa, e di parametrizzare lo script, cio\u00e8 trovare un modo per cambiare il numero palina dinamicamente, senza mettere mano allo script. Per la parametrizzazione, possiamo semplicemente prendere il numero palina e la chiave come parametri del nostro script. Aprendo il file \u201catac.py\u201d dalla cartella \u201cpalina\u201d del codice sorgente, possiamo quindi vedere che con l\u2019istruzione \u201c<em>NUMERO_PALINA = str(sys.argv[2])<\/em>\u201d assegniamo il valore del secondo parametro di linea di comando alla variabile numero palina.<\/p>\n<p style=\"text-align: justify;\">Per la selezione, invece, basta scorrere la lista \u201cprimi per palina\u201d con un ciclo \u201c<a href=\"https:\/\/docs.python.org\/2\/tutorial\/controlflow.html\">for<\/a>\u201d e selezionare con una serie di \u201c<a href=\"https:\/\/docs.python.org\/2\/tutorial\/controlflow.html\">if<\/a>\u201d gli arrivi con le propriet\u00e0 che pi\u00f9 ci interessano, per esempio non visualizzando gli arrivi delle linee non monitorate o quelle per le quali non \u00e8 previsto nessun arrivo. Dato il piccolo display a nostra disposizione dobbiamo rendere l\u2019output del nostro script pi\u00f9 leggibile: per fare ci\u00f2 eliminiamo i caratteri come le parentesi, e riduciamo parole come capolinea in \u201cCapol\u201d e fermate in \u201cFerm\u201d, facendo delle piccole <a href=\"https:\/\/docs.python.org\/2\/library\/string.html\">sostituzioni<\/a> &#8211; es: \u201d<em>.replace(&#8220;Capolinea&#8221;, &#8220;Capol&#8221;)<\/em>\u201d<em>.<\/em> Eseguendo lo script dalla riga di comando con \u201c<em>python atatc.py chiave_atac numero_fermata<\/em>\u201d avremo il seguente output:<br \/>\n<a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-35\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/5.png\" alt=\"Output\" width=\"597\" height=\"332\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/5.png 597w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/5-300x167.png 300w\" sizes=\"auto, (max-width: 597px) 100vw, 597px\" \/><\/a><\/p>\n<p class=\"normal\" style=\"text-align: center;\" align=\"center\">Che verr\u00e0 poi visualizzato sul display cos\u00ec:<\/p>\n<p class=\"normal\" style=\"text-align: justify;\" align=\"center\"><a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-36\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6.jpg\" alt=\"Output display\" width=\"609\" height=\"343\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6.jpg 609w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6-300x169.jpg 300w\" sizes=\"auto, (max-width: 609px) 100vw, 609px\" \/><\/a><\/p>\n<p class=\"normal\" style=\"text-align: justify;\">Per rendere il tutto pi\u00f9 solido possiamo anche aggiungere dei blocchi \u201c<a href=\"https:\/\/docs.python.org\/2\/tutorial\/errors.html\"><span style=\"color: #0563c1;\">try, except<\/span><\/a>\u201d per una corretta gestione delle <a href=\"http:\/\/it.wikipedia.org\/wiki\/Eccezione_%28informatica%29\"><span style=\"color: #0563c1;\">eccezioni<\/span><\/a>, in modo da non vedere \u201cesplodere\u201d il nostro script al primo problema.<\/p>\n<p><strong>Il demone Linux:<\/strong><\/p>\n<p style=\"text-align: justify;\">Per il controllo dello script python ho deciso di utilizzare un <a href=\"http:\/\/it.wikipedia.org\/wiki\/Demone_%28informatica%29\">demone linux<\/a> (che non ha nulla a che vedere con i Black Sabbath). In un sistema Unix\/Linux, un demone \u00e8 un programma o servizio che viene eseguito in background. Di norma un demone viene lanciato all\u2019avvio della macchina dal processo <a href=\"http:\/\/it.wikipedia.org\/wiki\/Init\">init<\/a>, che \u00e8 il primo processo ad essere eseguito dal <a href=\"https:\/\/it.wikipedia.org\/wiki\/Kernel\">kernel<\/a> dopo il <a href=\"http:\/\/it.wikipedia.org\/wiki\/Boot\">bootstrap<\/a>. Solitamente un demone \u00e8 composto da due parti:<\/p>\n<ul style=\"text-align: justify;\">\n<li>Uno script di controllo: invocato da init o dall\u2019utente per avviare, fermare o fare quel che si voglia con il demone. Questo viene scritto in un linguaggio di <a href=\"http:\/\/en.wikipedia.org\/wiki\/Shell_script\">scipting<\/a> per <a href=\"http:\/\/it.wikipedia.org\/wiki\/Shell_%28informatica%29\">shell<\/a>, fra le sue funzioni c\u2019\u00e8 anche quella di impedire che vengano eseguite due istanze dello stesso demone allo stesso tempo (impedendo l\u2019accesso concorrente alle risorse condivise).<\/li>\n<li>L\u2019eseguibile del demone, ovvero quella parte software che esegue ci\u00f2 per cui il demone viene creato. Nel nostro caso: temporizzare e parametrizzare la richiesta degli arrivi per una determinata palina. L\u2019eseguibile pu\u00f2 essere di qualsiasi tipo, ad esempio: un programma realizzato in <a href=\"http:\/\/it.wikipedia.org\/wiki\/C_%28linguaggio%29\">linguaggio c<\/a>, uno script <a href=\"http:\/\/it.wikipedia.org\/wiki\/Bash\">bash<\/a> o per assurdo uno script php(attraverso l\u2019interfaccia <a href=\"http:\/\/www.html.it\/articoli\/php-cli-php-da-linea-di-comando-1\/\">php-cli<\/a>).<\/li>\n<\/ul>\n<p class=\"normal\" style=\"text-align: justify;\">Per approfondire l\u2019argomento vi consiglio di leggere uno dei tanti tutorial presenti in rete, tra i quali per Linino\/Openwrt vi consiglio la <a href=\"http:\/\/wiki.openwrt.org\/doc\/techref\/initscripts\"><span style=\"color: #0563c1;\">nota tecnica<\/span><\/a> presente sul sito ufficiale di Openwrt.<\/p>\n<p class=\"normal\" style=\"text-align: justify;\">\u00a0Aprendo il file \u201c\/etc\/init.d\/pallina\u201d contenuto nell\u2019archivio del codice sorgente potrete vedere la mia implementazione dello script di controllo. Il codice \u00e8 commentato e dovrebbe essere di facile comprensione, l\u2019unica parte degna di nota \u00e8 forse il blocco \u201creload\u201d, nel quale dopo aver controllato che l\u2019eseguibile sia in esecuzione, invio il <a href=\"http:\/\/en.wikipedia.org\/wiki\/Unix_signal\"><span style=\"color: #0563c1;\">segnale<\/span><\/a> SIGUSR1. Questo segnale \u00e8 un segnale \u201cUser defined\u201d al quale si pu\u00f2 dare il significato che si vuole, nel mio caso lo uso per ordinare al programma ricevente di ricaricare le impostazioni dal file.<\/p>\n<p class=\"normal\" style=\"text-align: justify;\">Veniamo ora al corpo del demone: il file \u201c\/root\/pallina\/pallinad\u201d il quale \u00e8 scritto in <a href=\"http:\/\/it.wikipedia.org\/wiki\/Bash\"><span style=\"color: #0563c1;\">bash<\/span><\/a> (uno dei linguaggi di scripting pi\u00f9 usati al mondo). Linino non ha bash pre installato perch\u00e9 su openwrt la shell di default \u00e8 ash, per installare bash dovete eseguire i seguenti comandi: \u201copkg update; opkg install bash\u201d.<\/p>\n<p class=\"normal\" style=\"text-align: justify;\">Lo script parte chiamando la routine \u201cloadSettings\u201d la quale carica i parametri dal file \u201csettings.ini\u201d, in questo file sono troviamo: il numero palina da monitorare, la chiave atac e il numero di secondi da attendere prima di una nuova richiesta.<\/p>\n<p class=\"normal\" style=\"text-align: justify;\">Il secondo step e dichiarare due <a href=\"http:\/\/tldp.org\/LDP\/Bash-Beginners-Guide\/html\/sect_12_02.html\"><span style=\"color: #0563c1;\">Traps<\/span><\/a>:<\/p>\n<ul style=\"text-align: justify;\">\n<li>Una, per i segnali SIGHUP, SIGINT e SIGTERM che sono inviati dal sistema operativo per informare lo script di un\u2019imminente chiusura. Nel caso in cui uno di questi segnali venga ricevuto, l\u2019esecuzione si sposter\u00e0 al routine \u201cclean_up\u201d che termina l\u2019esecuzione dello script.<\/li>\n<li>L\u2019altra, per il segnale SIGUSR1 che, se ricevuto, porter\u00e0 all\u2019esecuzione della routine \u201creload\u201d, che ricarica i parametri di funzionamento dal file \u201csettings.ini\u201d.<\/li>\n<\/ul>\n<p class=\"normal\" style=\"text-align: justify;\">A questo punto informiamo il mondo dell\u2019avvio del demone in due modi:<\/p>\n<ul style=\"text-align: justify;\">\n<li>Invocando la routine \u201caddToLog \u2026\u201c che serve ad aggiungere una entry contente data e ora al file di log.<\/li>\n<li>Invocando la routine \u201csetOutputFile \u2026\u201d che serve ad impostare un valore nel file ultima.txt (il file che verr\u00e0 poi visualizzato sul display) aggiungendo un\u2019ulteriore riga contente una sequenza speciale di caratteri \u201c#*#\u201d, il cui scopo \u00e8 quello di indicare che la scrittura sul file \u00e8 completata.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Siamo ora nel vivo del codice. Dopo aver verificato che il parametro \u201cTIMER\u201d sia maggiore di 10 secondi(per evitare di bombardare il server con troppe richieste), siamo pronti per far partire il while che serve a creare il timer delle richieste. Fino a quando la variabile \u201cTIMER_ENABLED\u201d ha valore \u201cTRUE\u201d eseguiremo un semplice ciclo nel quale richiederemo le previsioni con la chiamata alla routine \u201caggiorna\u201d, per poi dormire per un numero di secondi uguale della variabile \u201cTIMER\u201d.<\/p>\n<p style=\"text-align: justify;\">Perch\u00e9 ho creato un ciclo che dorme (istruzione sleep) per un solo secondo alla volta, anzich\u00e9 dormire con unica istruzione per un numero di secondi pari al valore della variabile \u201cTIMER\u201d ? Ve lo spiego con un esempio: se sospendessimo l\u2019esecuzione per 15 secondi non avremmo la possibilit\u00e0 di ricevere nessun segnale dal sistema operativo per tutta la durata di questo tempo, cosa che renderebbe il nostro codice poco efficiente. Con il ciclo, invece, dormiamo per un solo secondo alla volta, processando le eventuali richieste dell\u2019OS in tempo per dare un feedback all\u2019utente.<\/p>\n<p style=\"text-align: justify;\">Nella routine \u201caggiorna\u201d dopo aver controllato che tutti i parametri necessari abbiano un valore, passiamo all\u2019azione con questa istruzione: \u201c$DOWNLOADER $CHIAVE_ATAC $NUMEROPALINA &gt; \/tmp\/tmp.txt 2&gt;&amp;1\u201d. Chiamiamo lo script python, che \u00e8 rappresentato dalla variabile \u201cDOWNLOADER=&#8221;python \/root\/pallina\/atac.py\u201d\u201d inviandogli i due parametri \u201c$CHIAVE_ATAC\u201d e \u201c$NUMEROPALINA\u201d, riversando l\u2019output nel file \u201ctmp.txt\u201d e non nel file \u201cultima.txt\u201d. Questo perch\u00e9, dobbiamo prima verificare che l\u2019output che vogliamo inviare al display contenga le previsioni della palina richiesta senza nessun errore, se tutto \u00e8 apposto possiamo versare il contenuto del file \u201ctmp.txt\u201d nel file \u201cultima.txt\u201d, aggiungendo quella strana sequenza di caratteri segnalati prima: \u201c#*#\u201d. Lo scopo di questa stringa \u00e8 quello di dichiarare che la scrittura del file \u00e8 terminata, in modo da evitare che sia Arduino che l\u2019interfaccia php leggano un file non completo. Questo perch\u00e9 ogni parte di questo progetto (Arduino, demone, interfaccia php) lavora in maniera asincrona.<\/p>\n<p><strong>L\u2019interfaccia web:<\/strong><\/p>\n<p style=\"text-align: justify;\">Come ben sappiamo, la cosa che rende Arduino Yun diverso da i suoi fratelli <a href=\"http:\/\/arduino.cc\/en\/Main\/arduinoBoardUno\">Uno<\/a> e <a href=\"http:\/\/arduino.cc\/en\/Main\/arduinoBoardLeonardo\">Leonardo<\/a>, sta nel fatto che Yun oltre ad essere un microcontrollore programmabile \u00e8 anche un piccolo computer Linux che pu\u00f2 fare affidamento su un vasto se non illimitato parco software fatto da: librerie, interpreti, server web ecc &#8230; estendendo di fatto le potenzialit\u00e0 della piattaforma Arduino. Fra questi c\u2019\u00e8 <a href=\"http:\/\/it.wikipedia.org\/wiki\/PHP\">php<\/a>, un linguaggio di scripting <a href=\"http:\/\/it.wikipedia.org\/wiki\/Lato_server\">lato server<\/a> che, ad oggi, viene usato da milioni di sviluppatori per rendere i loro siti web dinamici.<\/p>\n<p>Data questa possibilit\u00e0 ho deciso di realizzare un\u2019interfaccia web php, le cui funzioni sono:<\/p>\n<ul>\n<li>Avvio e Arresto del demone pallina.<\/li>\n<li>Cambio del numero palina\/fermata.<\/li>\n<li>Consultazione degli arrivi.<\/li>\n<li>Consultazione, Scarico ed Eliminazione del file di log.<\/li>\n<\/ul>\n<div id=\"attachment_41\" style=\"width: 358px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-41\" class=\"wp-image-41 size-full\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6.png\" alt=\"Interfaccia\" width=\"348\" height=\"637\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6.png 348w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/6-164x300.png 164w\" sizes=\"auto, (max-width: 348px) 100vw, 348px\" \/><\/a><p id=\"caption-attachment-41\" class=\"wp-caption-text\">L&#8217;interfaccia web<\/p><\/div>\n<p>Per installare php sul vostro yun seguite questi semplici passi:<\/p>\n<ul>\n<li>Da terminale: \u201copkg update; opkg install php5 php5-cgi php5-cli zoneinfo-europe\u201d.<\/li>\n<li>Sempre da terminale modificate il file \\\u201c\/etc\/config\/uhttpd\u201d togliendo la grata dalla riga \u201clist interpreter\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;.php=\/usr\/bin\/php-cgi&#8221;\\\u201d che attiver\u00e0 il supporto php per il nostro <a href=\"http:\/\/it.wikipedia.org\/wiki\/Server_web\">webserver<\/a>.<\/li>\n<li>Attivate il supporto per il nostro fuso orario aggiungendo questa riga \\\u201ddate.timezone = &#8220;Europe\/Rome&#8221;\\\u201d al file \u201c\/etc\/php.ini\u201d.<\/li>\n<li>Riavviate il vostro yun.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">I file che compongono l\u2019interfaccia si trovano nella cartella \u201c\/www\/sd\/\u201d. Il file \u201cmain.php\u201d \u00e8 la parte principale di questa interfaccia. La pagina \u00e8 composta da una tabella che contiene cinque righe, le quali contengono:<\/p>\n<ul>\n<li>Il blocco <a href=\"http:\/\/www.w3schools.com\/tags\/tag_div.asp\">&lt;div&gt;<\/a> \u201cstatus\u201d che con una cadenza di 15 secondi aggiorna lo stato del demone e genera il tasto di avvio e arresto. Il div viene creato dall\u2019esecuzione dello script php \u201cdeamon.php\u201d.<\/li>\n<li>Il riferimento allo scipt che visualizza e cambia il numero della pallina \u201ccambia_pallina.php\u201d.<\/li>\n<li>Il riferimento allo scipt che visualizza e cambia la chiave per accedere ai servizi Open Data \u201ccambia_pallina.php\u201d.<\/li>\n<li>Il blocco &lt;div&gt; \u201cfile_arrivi\u201d che con una cadenza di 5 secondi visualizza il contenuto del file \u201cultima.txt\u201d, questo div viene creato con l\u2019esecuzione dello script php \u201cleggi_arrivi.php\u201d.<\/li>\n<li>Il blocco &lt;div&gt; \u201clog_file\u201d che con una cadenza di 5 secondi visualizza il contenuto del file di log con l\u2019esecuzione dello script php \u201cleggi_log.php\u201d.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Per aggiornare le varie parti della pagina senza ricaricare la pagina stessa, uso <a href=\"http:\/\/it.wikipedia.org\/wiki\/JQuery\">jQuery<\/a>, un potentissimo framework gratuito basato su <a href=\"http:\/\/it.wikipedia.org\/wiki\/JavaScript\">javascript<\/a> che con poche righe di codice vi permette di dotare di effetti dinamici le vostre pagine web.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-45\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/8.png\" alt=\"main.php\" width=\"527\" height=\"324\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/8.png 527w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/8-300x184.png 300w\" sizes=\"auto, (max-width: 527px) 100vw, 527px\" \/><\/a>In questo piccolo esempio tratto da \u201cmain.php\u201d definisco due funzioni:<\/p>\n<ul style=\"text-align: justify;\">\n<li>Una che viene invocata ogni 5 secondi per generare i div contenenti gli arrivi e il file di log.<\/li>\n<li>L\u2019atra che viene invocata ogni 15 secondi per generare il div \u201cstatus\u201d.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Il resto dei file previa lettura dovrebbe essere di facile comprensione. Se avete dubbi o non riuscite a capire parte del codice, lasciate un commento a fine articolo, tempo permettendo cercher\u00f2 di rispondervi.<\/p>\n<p><strong>Lo Sketch Arduino:<\/strong><\/p>\n<p style=\"text-align: justify;\">In tutti o quasi i miei progetti troverete l&#8217;uso del <a href=\"http:\/\/en.wikipedia.org\/wiki\/Watchdog_timer\">watchdog<\/a> e di un led di stato, questo perch\u00e9 il watchdog aumenta l\u2019affidabilit\u00e0 del software, e il led di stato informa l\u2019utente della vitalit\u00e0 del sistema. In un sistema di controllo lo scopo del watchdog \u00e8 quello di resettare il microprocessore\\microcontrollore se questo non risponde ad uno stimolo entro una <a href=\"http:\/\/en.wikipedia.org\/wiki\/Time_limit\">deadline<\/a> (Intervallo di tempo) configurabile. Il microcontrollore del nostro Arduino Yun (che \u00e8 un <a href=\"http:\/\/www.atmel.com\/devices\/atmega32u4.aspx\">ATmega32u4<\/a>) \u00e8 dotato anche di un watchdog configurabile, che pu\u00f2 arrivare ad una deadline massima di 8 secondi.<\/p>\n<p style=\"text-align: justify;\">Su Arduino l&#8217;accesso alle funzionalit\u00e0 del watchdog avviene grazie alla libreria &#8220;<a href=\"http:\/\/www.nongnu.org\/avr-libc\/user-manual\/group__avr__watchdog.html\">avr\/wdt.h<\/a>&#8220;, che ha sostanzialmente tre routine:<\/p>\n<ul style=\"text-align: justify;\">\n<li>\u201cwdt_disable()\u201d: per disabilitare il watchdog.<\/li>\n<li>\u201cwdt_enable(WDTO_4S)\u201d: per attivare il watchdog settando la lunghezza della deadline.<\/li>\n<li>\u201cwdt_reset()\u201d: per resettarne il contatore.<\/li>\n<\/ul>\n<p class=\"normal\" style=\"margin-bottom: .0001pt; text-align: justify;\">Se guardate il blocco <a href=\"http:\/\/arduino.cc\/en\/Reference\/Setup\">setup<\/a> (quello eseguito all&#8217;avvio dello schetch) del file &#8220;yunlcd.ino\u201d, potrete vedere che la prima cosa che faccio \u00e8 quella di disabilitare il watchdog (nel caso fosse rimasto attivo dall&#8217;ultimo reset), eseguo poi tutte le operazioni necessarie all&#8217;avvio dello schetch e, prima di passare alla routine <a href=\"http:\/\/arduino.cc\/en\/Reference\/loop\">loop<\/a>, abilito il watchdog con una deadline di 4 secondi. Questo far\u00e0 si che se per un tempo maggiore di 4 secondi NON resetto il watchdog, questo resetter\u00e0 il Microcontrollore dello yun. La lunghezza della deadline dipende dal tipo di applicazione che state realizzando, ma su questo argomento si sono dibattuti in tanti, quindi non vado oltre poich\u00e8 ne potremmo parlare per giorni, se non per mesi. Se ne siete interessati, la rete ha tutte le risposte che cercate. Se avete seguito il mio discorso, avrete anche capito che da questo momento non potete interrompere il flusso di esecuzione con l\u2019istruzione <a href=\"http:\/\/arduino.cc\/en\/Reference\/Delay\">delay<\/a> per pi\u00f9 di quattro secondi, a meno che non vogliate forzatamente resettare il vostro Arduino. Quindi, cosa si pu\u00f2 fare in questo caso? Semplice, si pu\u00f2 dividere il tempo per il quale si deve \u201cdormire\u201d in piccoli <a href=\"http:\/\/it.wiktionary.org\/wiki\/time_slice\">time slice<\/a> (termine preso in prestito dai sistemi in <a href=\"http:\/\/en.wikipedia.org\/wiki\/Time-sharing\">time sharing<\/a>) e al termine di ognuno di questi si pu\u00f2 resettare il watchdog, fino ad arrivare ad una somma di time slice uguale al tempo per il quale vogliamo dormire. Questo si vede nella routine wdDelay nel file &#8220;yunlcd.ino\u201d:<\/p>\n<p class=\"normal\" style=\"margin-bottom: .0001pt; text-align: justify;\"><a href=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/7.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-48\" src=\"http:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/7.png\" alt=\"Sketch Arduino\" width=\"331\" height=\"376\" srcset=\"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/7.png 331w, https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/7-264x300.png 264w\" sizes=\"auto, (max-width: 331px) 100vw, 331px\" \/><\/a>Dove ho anche aggiunto la funzionalit\u00e0 del led di stato, con la routine \u201cled()\u201d che come prima cosa resetta il watchdog e, se necessario, cambia lo stato del led da accesso a spento con una frequenza definita nella variabile \u201cnextLedTick\u201d. Se dopo aver letto il codice avete ancora le idee confuse sulla <a href=\"http:\/\/it.wikipedia.org\/wiki\/Multitasking\"><span style=\"color: #0563c1;\">multiprogrammazione<\/span><\/a> con Arduino, vi consiglio di leggere <a href=\"http:\/\/arduino.cc\/en\/Tutorial\/BlinkWithoutDelay\"><span style=\"color: #0563c1;\">questo tutorial<\/span><\/a> che vi spiegher\u00e0 come far lampeggiare un led senza l\u2019uso del classico delay.<\/p>\n<p class=\"normal\" style=\"margin-bottom: .0001pt; text-align: justify;\">Il resto del codice si concentra sulla scrittura nel display del contenuto del file \u201c\/pallina\/ultima.txt\u201cche come sappiamo contiene le previsioni di arrivo. Il display che ho deciso di utilizzare in questo progetto \u00e8 un 4 righe per 20 caratteri di tipo seriale (LCM1602 IIC V1). Questo tipo di display si controlla con solo 2 cavi e con un costo leggermente superiore a quello dei display paralleli vi permette di perdere meno tempo nei collegamenti, e lascia liberi alle vostre esigenze gli altri pin di input\/output. La libreria che vi permette di interfacciarvi con questo tipo di display \u00e8 la \u201cLiquidCrystal_I2C\u201d, che potete trovare a <a href=\"http:\/\/arduino-info.wikispaces.com\/LCD-Blue-I2C\"><span style=\"color: #0563c1;\">questo indirizzo<\/span><\/a>, con relativi esempi di utilizzo. Credo che il resto del codice accompagnato dai relativi commenti sia di facile comprensione, l\u2019unica cosa che potrebbe darvi noia, se non l\u2019avete vista prima, \u00e8 la <a href=\"http:\/\/it.wikipedia.org\/wiki\/Coda_%28informatica%29\"><span style=\"color: #0563c1;\">coda<\/span><\/a> \u201cQueueList &lt;String&gt; queue;\u201d che uso per memorizzare le righe contenute nel file delle previsioni. In generale una struttura dati \u00e8 un modo per rappresentare dei dati in un computer, sono esempi di strutture dati: le variabili, gli array(vettori) e le code. <a href=\"http:\/\/en.wikipedia.org\/wiki\/Queue_%28abstract_data_type%29\"><span style=\"color: #0563c1;\">Le code<\/span><\/a> sono strutture dati di tipo <a href=\"http:\/\/en.wikipedia.org\/wiki\/FIFO\"><span style=\"color: #0563c1;\">FIFO<\/span><\/a>, il primo dato ad essere inserito(con l\u2019operazione push) \u00e8 anche il primo ad essere estratto(con l\u2019operazione pop). In Arduino le code si implementano con la <a href=\"http:\/\/it.wikipedia.org\/wiki\/Classe_%28informatica%29\"><span style=\"color: #0563c1;\">classe<\/span><\/a> \u201cQueueList\u201d che potete trovare <a href=\"http:\/\/playground.arduino.cc\/Code\/QueueList\"><span style=\"color: #0563c1;\">qui<\/span><\/a>, nel mio esempio questa contiene delle stringhe ma pu\u00f2 contenere qualsiasi tipo di dato. Come detto in precedenza se avete dubbi o non riuscite a capire parte del codice, lasciate un commento a fine articolo, tempo permettendo cercher\u00f2 di rispondervi.<\/p>\n<p><strong>Conclusioni:<\/strong><\/p>\n<p>Lo scopo che mi ero preposto in questo primo articolo era quello di mostrare Arduino Yun nel pieno della sua potenza, con un esempio pratico che mostrasse la parte Linux al fianco di quella classica. Un fattore che credo non debba essere sottovalutato quando si sviluppa con Arduino Yun \u00e8 la <a href=\"http:\/\/it.wikipedia.org\/wiki\/Portabilit%C3%A0\">portabilit\u00e0 del codice<\/a> che con poche modifiche pu\u00f2 girare su qualsiasi piattaforma Linux, rendendo Arduino Yun una economica piattaforma di apprendimento, oltre che un potente strumento per lo sviluppo delle proprie idee. Spero che sia l\u2019articolo che il <a title=\"basduino v0.1\" href=\"http:\/\/www.prioprio.it\/wordpress\/download\/basduino-v0-1\/\" target=\"_blank\">codice allegato<\/a> (che \u00e8 sotto licenza <a href=\"http:\/\/www.gnu.org\/licenses\/gpl-2.0.html\">GNU GPL V2<\/a>) possa esservi d\u2019aiuto o spunto, se avete domande, commenti o idee non esitate a postarle.<\/p>\n<p>Alla prossima.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Era da tempo che cercavo un progettino sul quale cimentarmi con il mio arduino yun, uno di quelli che mi impegnasse almeno pi\u00f9 di un giorno, quando, camminando per Roma, mi sono imbattuto in uno di questi pannelli. L\u2019Atac &hellip; <a href=\"https:\/\/www.prioprio.it\/wordpress\/basduino\/\">Continua a leggere<span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":54,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[11,12],"tags":[2,6,9,4,5,17,8,16,3,10,7,18],"class_list":["post-16","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino","category-linux","tag-arduino","tag-arduino-yun","tag-bash","tag-bus","tag-display","tag-i2c","tag-jquery","tag-lcd","tag-linux","tag-open-data","tag-php","tag-roma"],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/s5GgEM-basduino","jetpack_featured_media_url":"https:\/\/www.prioprio.it\/wordpress\/wp-content\/uploads\/2015\/02\/icona.png","_links":{"self":[{"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/posts\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/comments?post=16"}],"version-history":[{"count":35,"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":75,"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/posts\/16\/revisions\/75"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/media\/54"}],"wp:attachment":[{"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/media?parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/categories?post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.prioprio.it\/wordpress\/wp-json\/wp\/v2\/tags?post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}