Questo progetto
IoT, realizzato con
ESP8266, permette di comandare, tramite una pagina
WEB, e quindi anche da
cellulare o
tablet, un qualsiasi dispositivo controllabile con un telecomando a
infrarossi.
SchemaIl diodo LED infrarosso deve essere orientato verso gli apparati da controllare e non devono esserci ostacoli in mezzo.
Su alcuni telefoni, soprattutto in passato, era presente un LED emettitore a infrarossi, quindi si trovavano delle APP che funzionavano come telecomando.
Sui modelli recenti il LED non è più presente.
Questo progetto permette di superare la limitazione data dalla mancanza del LED.
Pagine WEB
Le schermate dell'applicativo, che possono essere richiamate dall'indirizzo
http://192.168.0.50/, sono queste
SchermateLa prima pagina permette di controllare un
televisore LG, la seconda un
Home Teatre Onkio e l'ultima permette di iserire un qualsiasi codice per
test.
Tramite
swipe, destro o sinistro, è possibile cambiare schermata.
Il circuito funziona implementando un
web server che risponde a queste url:
L'indirizzo IP andrà personalizzato in base alle impostazione della rete WI-FI.
API
In particolare l'API
http://<indirizzoIP>/ir vuole 4 parametri, ad esempio
http://192.168.0.50/ir?mode=nec&code=0x4BB6C03F&bits=32&repeat=1&t=1625427666318
e ritrasmette il codice infrarosso.
I parametri sono:
- mode: tipo di codifica da utiliizare per inviare i codici infrarosso
- code: codice da inviare espresso in esadecimale
- bits: numero di bit di cui è composto il codice
- repeat: numero di ripetizioni del codice, solitamente sempre 1
- t: timestamp opzionale (solo per essere sicuro che il browser non faccia cache delle chiamate)
La url può essere richiamata da qualunquu applicativo o
script.
Realizzazione
Per la realizzazione del circuito serve:
- nr. 1 ESP8266
- nr. 1 LED emettitore all'infrarosso
- nr. 1 transistor BC 548 C
- nr. 1 resistenza da 22 ohm 1/4 W
- nr. 1 resistenza da 2200 ohm 1/4 W
- nr. 1 alimentatore a 5V d.c.
- nr. 1 una breadboard
- fili vari
Schema elettricoche in pratica diventa
Realizzazione praticaIn alternativa è possibile usare il modulo
IR, anche se dalle prove effettuate il raggio infrarossi sembra essere più direzionale e meno potente
Realizzazione pratica con modulo IRProgrammazione
Il circuito va poi programmato, tramite l'
IDE di Arduino, con il codice seguente che comprende la parte lato client
HTML e
JavaScript altre alla parte lato server per
Arduino/*
Sgart.it IR (infrared) Server
Version 1.0 Jul 2018/2021
Copyright 2018 Sgart.it
https://www.sgart.it//IT/elettro/televisore-comandato-dal-cellulare-o-via-web-esp8266/post
Board: 'Generic ESP8266 Module'
Flash Mode: 'DIO'
Flash Size: '1M (512KSPIFFS)'
Debug Port: 'Disabled'
Debug Level: 'None'
Reset Method: 'nodemcu'
Crystal frequency: '26MHz'
Flash Frequency '40MHz'
CPU Frequency '80 MHz'
Upload Speed: '115200'
Port: COM3
*/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <IRsend.h>
extern "C" {
#include "user_interface.h"
uint16 readvdd33(void);
bool wifi_set_sleep_type(sleep_type_t);
sleep_type_t wifi_get_sleep_type(void);
}
/*
* parametri da adeguare alla propria rete
*/
// impostazioni WI-FI
const String WIFI_SSID = "<SSID wi-fi>";
const String WIFI_PASSWORD = "<WI-FI password>";
// IP statico
IPAddress ip(192, 168, 0, 50);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
const String VERSION_STR = "HTTP IR Server v. 1.0 - 2018/2021 - Sgart.it";
ESP8266WebServer server(80);
//gestione pin trasmettitore infrarosso (ESP8266 GPIO4 - D2)
#define IR_LED 4
IRsend irsend(IR_LED);
//gestione pagina html iniziale (home)
void handleHome() {
server.send(200, "text/html",
"<html>"
"<head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>IR Server - Sgart.it</title>"
"<link rel='shortcut icon' href='https://www.sgart.it/favicon.ico' type='image/x-icon'>"
"<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>"
"<meta name='application-name' content='IR - Sgart.it'><meta name='msapplication-TileColor' content='#500000'>"
"<style>.navbar{margin-bottom:5px;} .navbar-header{width:100%;} .btn{display:block;width:100%;min-height:40px;} .row>div{padding:10px;} hr{margin: 10px 0}"
"#btn-off{display:block;float:right;} #loading{position:fixed;top:0;left:0;right:0;bottom:0;;background-color:rgba(200,200,200,.5);z-index:99999;display:none;}"
"</style></head><body>"
"<div id='loading'></div>"
"<nav class='navbar navbar-default'><div class='container0'><div class='navbar-header'>"
"<a class='navbar-brand' href='https://www.sgart.it/?remote-control\'><img src='https://www.sgart.it/content/images/sgart32.png'></a>"
"<button type='button' class='navbar-toggle btn-lg' id='btn-off' onclick='send(\"nec-20DF10EF,nec-4B36D32C\")'><i class='glyphicon glyphicon-off text-danger'></i></button>"
"<button type='button' class='navbar-toggle' id='btn-tv-tuner' onclick='changeCard(1)' style='display:block'>Tuner</button>"
"<h3 id='title'>Sgart.it</h3>"
"</div></div></nav>"
"<!-- BEGIN: CONTAINER --> <div class='container'>"
"<!-- BEGIN: CARD TV --> <div id='card-0' data-title='TV' data-cmd-disabled='nec-4BB6906F,nec-20DF23DC'>"
"<div class='row'>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4BB6A05F\")'><i class='glyphicon glyphicon-volume-off'></i><br><span>Mute</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF3EC1\")'><i class='glyphicon glyphicon-home'></i><br><span>Home</button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DFC23D\")'><i class='glyphicon glyphicon-cog'></i><br><span>Settings</span></button></div>"
"</div>"
"<div class='row'><!--vol +: 20DF40BF, vol -: 20DFC03F, mute: 20DF906F-->"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-20DF40BF,nec-4BB640BF\")'><i class='glyphicon glyphicon-chevron-up'></i><br><span>Vol. +</span></button></div>"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-20DF00FF\")'><i class='glyphicon glyphicon-chevron-up'></i><br><span>Prg. +</span></button></div>"
"</div>"
"<div class='row'>"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-20DFC03F,nec-4BB6C03F\")'><i class='glyphicon glyphicon-chevron-down'></i><br><span>Vol. -</span></button></div>"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-20DF807F\")'><i class='glyphicon glyphicon-chevron-down'></i><br><span>Prg. -</span></button></div>"
"</div>"
"<div class='row'>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF55AA\")'><i class='glyphicon glyphicon-info-sign'></i><br><span>Info</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-info' onclick='send(\"nec-20DF02FD\")'><i class='glyphicon glyphicon-menu-up'></i><br><span>Up</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DFCA35\")'><span>LIVE MENU</span></button></div>"
"</div>"
"<div class='row'>"
"<div class='col-xs-4'><button class='btn btn-xs btn-info' onclick='send(\"nec-20DFE01F\")'><i class='glyphicon glyphicon-menu-left'></i><br><span>Left</button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF22DD\")'><i class='glyphicon glyphicon-ok'></i><br><span>OK</button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-info' onclick='send(\"nec-20DF609F\")'><i class='glyphicon glyphicon-menu-right'></i><br><span>Right</span></button></div>"
"</div>"
"<div class='row'>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF14EB\")'><i class='glyphicon glyphicon-arrow-left'></i><br><span>Back</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-info' onclick='send(\"nec-20DF827D\")'><i class='glyphicon glyphicon-menu-down'></i><br><span>Down</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DFDA25\")'><i class='glyphicon glyphicon-remove'></i><br><span>Exit</span></button></div>"
"</div>"
"<hr> <!-- KEYS -->"
"<div class='row'>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF8877\")'><span>1</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF48B7\")'><span>2</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DFC837\")'><span>3</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF28D7\")'><span>4</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DFA857\")'><span>5</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF6897\")'><span>6</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DFE817\")'><span>7</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF18E7\")'><span>8</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF9867\")'><span>9</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DFD52A\")'><span>GUIDE</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF08F7\")'><span>0</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-20DF58A7\")'><span>Q.VIEW</span></button></div>"
"</div>"
"<hr>"
"<div class='row'>"
"<div class='col-xs-6'><button class='btn btn-xs btn-success' onclick='send(\"nec-20DF23DC\")'><span>ON</span></button></div>"
"<div class='col-xs-6'><button class='btn btn-xs btn-danger' onclick='send(\"nec-20DFA35C\")'><span>OFF</span></button></div>"
"</div>"
"</div> <!-- END: CARD TV --> " \
"<!-- BEGIN: CARD TUNER --> <div id='card-1' data-title='Tuner' data-cmd-disabled='nec-4BB6D02F,nec-20DFA35C' style='display:none'>"
"<div class='row'>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4BB6D02F\")'><span>AM / FM</span></button></div>"
"<div class='col-xs-4'></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B36AA55\")'><span>DISPLAY</span></button></div>"
"</div>"
"<div class='row'><!--vol +: 20DF40BF, vol -: 20DFC03F, mute: 20DF906F-->"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-4BB640BF\")'><i class='glyphicon glyphicon-chevron-up'></i><br><span>Vol. +</span></button></div>"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-4BB600FF\")'><i class='glyphicon glyphicon-chevron-up'></i><br><span>Prg. +</span></button></div>"
"</div>"
"<div class='row'>"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-4BB6C03F\")'><i class='glyphicon glyphicon-chevron-down'></i><br><span>Vol. -</span></button></div>"
"<div class='col-xs-6'><button class='btn btn-primary' onclick='send(\"nec-4BB6807F\")'><i class='glyphicon glyphicon-chevron-down'></i><br><span>Prg. -</span></button></div>"
"</div>"
"<hr> <!-- KEYS -->"
"<div class='row'>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B40AB54\")'><span>1</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B406B94\")'><span>2</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B40EB14\")'><span>3</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B401BE4\")'><span>4</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B409B64\")'><span>5</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B405BA4\")'><span>6</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B40DB24\")'><span>7</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B403BC4\")'><span>8</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B40BB44\")'><span>9</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B40FB04\")'><span>D.TUN</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4B407B84\")'><span>0</span></button></div>"
"<div class='col-xs-4'><button class='btn btn-xs btn-default' onclick='send(\"nec-4BB6BA45\")'><span>SLEEP</span></button></div>"
"</div>"
"</div> <!-- END: CARD TUNER -->"
"<!-- BEGIN: CARD TEST CODE --> <div id='card-2' data-title='Test code' data-cmd-disabled='' style='display:none'>"
"<div class='row'>"
"<div class='col-xs-9'>"
"<span><select id='m' class='form-control'><option value='nec' selected>NEC</option><option value='rc5'>RC5</option><option value='rc6'>RC6</option></select></span>"
"<span><input type='text' id='c' value='20DFCA35' placeholder='code' class='form-control'></span>"
"<span><input type='text' id='b' value='32' placeholder='bits' class='form-control'></span>"
"<span><input type='text' id='r' value='1' placeholder='repeat' class='form-control'></span>"
"</div>"
"<div class='col-xs-3'><button class='btn btn-xs btn-default' onclick='sendTest()'><i class='glyphicon glyphicon-play'></i><br><span>Test</span></button></div>"
"</div> <!-- END: CARD TEST -->"
"</div> <!-- END: CONTAINER --> "
"<script> "
"/* libreria per swipe */ "
"!function(t,e){'use strict';'initCustomEvent'in e.createEvent('CustomEvent')&&(t.CustomEvent=function(t,n){n=n||{bubbles:!1,cancelable:!1,detail:void 0};var u=e.createEvent('CustomEvent');return u.initCustomEvent(t,n.bubbles,n.cancelable,n.detail),u},t.CustomEvent.prototype=t.Event.prototype),e.addEventListener('touchstart',function(t){if('true'===t.target.getAttribute('data-swipe-ignore'))return;l=t.target,i=Date.now(),n=t.touches[0].clientX,u=t.touches[0].clientY,a=0,o=0},!1),e.addEventListener('touchmove',function(t){if(!n||!u)return;var e=t.touches[0].clientX,i=t.touches[0].clientY;a=n-e,o=u-i},!1),e.addEventListener('touchend',function(t){if(l!==t.target)return;var e=parseInt(l.getAttribute('data-swipe-threshold')||'20',10),s=parseInt(l.getAttribute('data-swipe-timeout')||'500',10),r=Date.now()-i,c='';Math.abs(a)>Math.abs(o)?Math.abs(a)>e&&r<s&&(c=a>0?'swiped-left':'swiped-right'):Math.abs(o)>e&&r<s&&(c=o>0?'swiped-up':'swiped-down');''!==c&&(l.dispatchEvent(new CustomEvent(c,{bubbles:!0,cancelable:!0})),console&&console.log&&console.log(c+' fired on '+l.tagName));n=null,u=null,i=null},!1);var n=null,u=null,a=null,o=null,i=null,l=null}(this,document);"
"/* main */ "
"function getId(id){ return document.getElementById(id) }"
"/* gestione swipe - card */ "
"var cardIndex = 0, cardIndexMax = 2;"
"document.addEventListener('swiped-left', function(e) { changeCard(1); }); document.addEventListener('swiped-right', function(e) { changeCard(-1); });"
"function changeCard(moveIndex) { cardIndex += moveIndex; if(cardIndex < 0) cardIndex = cardIndexMax; else if (cardIndex > cardIndexMax) cardIndex = 0; showCard(); }"
"function showCard(){"
"/* card corrente */"
"var objCard = getId('card-'+cardIndex); var title=objCard.getAttribute('data-title');"
"getId('title').innerText=title; objCard.style.display='block';"
"/* next button */"
"var cardIndexNext = cardIndex >= cardIndexMax ? 0 : cardIndex + 1; objCardNext = getId('card-' + cardIndexNext); var titleNext = objCardNext.getAttribute('data-title'); getId('btn-tv-tuner').innerHTML = titleNext;"
"/* disattivo schede */"
"for(var i=0; i<=cardIndexMax; i++) { if(cardIndex!==i) getId('card-'+i).style.display='none'; }"
"var cmd=objCard.getAttribute('data-cmd'); send(cmd);};"
"showCard();"
"/* test code */"
"function sendTest(){ var m=getId('m').value; var c=getId('c').value; var b=getId('b').value; var r=getId('r').value; sendFull(m,c,b,r); }"
"/* invia comandi */"
"function send(cmds){ if(cmds===null) return; var cmd=cmds.split(','); for(var i=0;i<cmd.length;i++){ var m='',c='',b=null,r=null; var p=cmd[i].split('-');"
"if(p.length>0) m=p[0]; if(p.length>1) c=p[1]; if(p.length>2) b=p[2]; if(p.length>3) r=p[3]; sendFull(m,c,b,r); }}"
"function sendFull(m,c,b,r){ try{"
"if(b===undefined || b==null || b==='' || b<=0) b=32; if(r===undefined || r==null || r==='' || r<=0) r=1;"
"var url = '/ir?mode='+m.toLowerCase()+'&code=0x' + c + '&bits=' + b + '&repeat=' + r + '&t=' + (new Date().getTime());"
"sendHttp(url); }catch(e){ console.log(e); } }"
"/* chiamata http */ "
"function sendHttp(url){ var loading=document.getElementById('loading'); loading.style.display='block';"
"try{ var xhr = new XMLHttpRequest(); xhr.open('GET', url);"
"xhr.onload = function() { loading.style.display='none'; if (xhr.status === 200) { console.log('OK'); } else { alert('Error: ' + xhr.status); }};"
"xhr.onerror = function() { loading.style.display='none'; alert(\"Errore nell'invio del codice\"); };"
"xhr.send(); }catch(e){ loading.style.display='none'; alert(e); } }"
" </script> </body></html>");
}
// gestisce l'arrivo di una richiesta http (pagina /ir?mode=XX&code=0xXXXX&bits=XX&repeat=X
// e trasmette il corrispondente codice tramite un led infrarosso (IR)
void handleIR() {
unsigned long code = 0;
unsigned int bits = 32;
unsigned int repeat = 1;
String mode = "";
//leggo i parametri dalla querystring
for (uint8_t i = 0; i < server.args(); i++) {
if (server.argName(i) == "code") {
code = strtoul(server.arg(i).c_str(), NULL, 16);
} else if (server.argName(i) == "mode") {
mode = server.arg(i).c_str();
} else if (server.argName(i) == "bits") {
bits = strtoul(server.arg(i).c_str(), NULL, 10);
} else if (server.argName(i) == "repeat") {
repeat = strtoul(server.arg(i).c_str(), NULL, 10);
}
}
// invio i codici
String choose = "?";
if (mode == "nec" && code != 0) {
choose = "NEC";
irsend.sendNEC(code, bits, repeat);
} else if (mode == "rc5" && code != 0) {
choose = "RC5";
irsend.sendRC5(code, bits);
} else if (mode == "rc6" && code != 0) {
choose = "RC6";
irsend.sendRC6(code, bits);
}
printCode(choose, mode, code, bits, repeat);
// risposta
if (choose == "?") {
server.send(400, "text/html", "Bad Request: IR Protocol not found.");
} else {
server.send(200, "text/html", "OK");
// piccola pausa
delay(40);
}
}
// visualizzo i parametri inviati in console
void printCode(String choose, String mode, unsigned long code, unsigned int bits, unsigned int repeat) {
Serial.print("mode: ");
Serial.print(mode);
Serial.print(", code: ");
Serial.print(code, HEX);
Serial.print(", bits: ");
Serial.print(bits);
Serial.print(", repeat: ");
Serial.print(repeat);
Serial.print(", choose: ");
Serial.println(choose);
}
// pagina non torvata
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++)
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
server.send(404, "text/plain", message);
}
// setup iniziale
void setup(void) {
Serial.begin(115200);
Serial.println("");
Serial.println("");
// Wait for connection
Serial.print("WI-FI '" + WIFI_SSID + "' connecting");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to WI-FI: " + WIFI_SSID);
// setto l'IP statico
WiFi.config(ip, gateway, subnet);
Serial.println("");
Serial.println("IP set " + ip.toString());
// evito che il wifi si disattivi per risparmiare energia
wifi_set_sleep_type(NONE_SLEEP_T);
irsend.begin();
Serial.println("IR started");
// url gestire
server.on("/", handleHome); // pagina web
server.on("/ir", handleIR); // api send IR
server.on("/version", []() { // pagina versione
server.send(200, "text/plain", VERSION_STR);
});
server.onNotFound(handleNotFound);
server.begin();
Serial.println("Web server started http://" + WiFi.localIP().toString() + "/");
//reset ???
irsend.sendNEC(0, 32, 3);
Serial.println(VERSION_STR);
}
//gestione loop
void loop(void) {
server.handleClient();
}
Modificando le variabili:
- WIFI_SSID: con l'SSID della rete WI_FI (2,4GHz)
- WIFI_PASSWORD: la password di accesso alla rete
- ip: l'indirizzo IP da assegnare staticamente
- subnet: netmask della rete
- gateway: gateway della rete (solitamente l'IP del router)
Dettaglio del codice
Per una migliore leggibilità riporto l'
HTML generato
<div id='loading'></div>
<nav class='navbar navbar-default'>
<div class='container0'>
<div class='navbar-header'>
<a class='navbar-brand' href='https://www.sgart.it/?remote-control'>
<img src='https://www.sgart.it/content/images/sgart32.png'>
</a>
<button type='button' class='navbar-toggle btn-lg' id='btn-off' onclick='send("nec-20DF10EF,nec-4B36D32C")'>
<i class='glyphicon glyphicon-off text-danger'></i>
</button>
<button type='button' class='navbar-toggle' id='btn-tv-tuner' onclick='changeCard(1)' style='display:block'>Tuner</button>
<h3 id='title'>Sgart.it</h3>
</div>
</div>
</nav>
<!-- BEGIN: CONTAINER -->
<div class='container'>
<!-- BEGIN: CARD TV -->
<div id='card-0' data-title='TV' data-cmd-disabled='nec-4BB6906F,nec-20DF23DC'>
<div class='row'>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4BB6A05F")'>
<i class='glyphicon glyphicon-volume-off'></i>
<br>
<span>Mute</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF3EC1")'>
<i class='glyphicon glyphicon-home'></i>
<br>
<span>Home
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DFC23D")'>
<i class='glyphicon glyphicon-cog'></i>
<br>
<span>Settings</span>
</button>
</div>
</div>
<div class='row'>
<!--vol +: 20DF40BF, vol -: 20DFC03F, mute: 20DF906F-->
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-20DF40BF,nec-4BB640BF")'>
<i class='glyphicon glyphicon-chevron-up'></i>
<br>
<span>Vol. +</span>
</button>
</div>
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-20DF00FF")'>
<i class='glyphicon glyphicon-chevron-up'></i>
<br>
<span>Prg. +</span>
</button>
</div>
</div>
<div class='row'>
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-20DFC03F,nec-4BB6C03F")'>
<i class='glyphicon glyphicon-chevron-down'></i>
<br>
<span>Vol. -</span>
</button>
</div>
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-20DF807F")'>
<i class='glyphicon glyphicon-chevron-down'></i>
<br>
<span>Prg. -</span>
</button>
</div>
</div>
<div class='row'>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF55AA")'>
<i class='glyphicon glyphicon-info-sign'></i>
<br>
<span>Info</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-info' onclick='send("nec-20DF02FD")'>
<i class='glyphicon glyphicon-menu-up'></i>
<br>
<span>Up</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DFCA35")'>
<span>LIVE MENU</span>
</button>
</div>
</div>
<div class='row'>
<div class='col-xs-4'>
<button class='btn btn-xs btn-info' onclick='send("nec-20DFE01F")'>
<i class='glyphicon glyphicon-menu-left'></i>
<br>
<span>Left
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF22DD")'>
<i class='glyphicon glyphicon-ok'></i>
<br>
<span>OK
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-info' onclick='send("nec-20DF609F")'>
<i class='glyphicon glyphicon-menu-right'></i>
<br>
<span>Right</span>
</button>
</div>
</div>
<div class='row'>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF14EB")'>
<i class='glyphicon glyphicon-arrow-left'></i>
<br>
<span>Back</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-info' onclick='send("nec-20DF827D")'>
<i class='glyphicon glyphicon-menu-down'></i>
<br>
<span>Down</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DFDA25")'>
<i class='glyphicon glyphicon-remove'></i>
<br>
<span>Exit</span>
</button>
</div>
</div>
<hr>
<!-- KEYS -->
<div class='row'>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF8877")'>
<span>1</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF48B7")'>
<span>2</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DFC837")'>
<span>3</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF28D7")'>
<span>4</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DFA857")'>
<span>5</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF6897")'>
<span>6</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DFE817")'>
<span>7</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF18E7")'>
<span>8</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF9867")'>
<span>9</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DFD52A")'>
<span>GUIDE</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF08F7")'>
<span>0</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-20DF58A7")'>
<span>Q.VIEW</span>
</button>
</div>
</div>
<hr>
<div class='row'>
<div class='col-xs-6'>
<button class='btn btn-xs btn-success' onclick='send("nec-20DF23DC")'>
<span>ON</span>
</button>
</div>
<div class='col-xs-6'>
<button class='btn btn-xs btn-danger' onclick='send("nec-20DFA35C")'>
<span>OFF</span>
</button>
</div>
</div>
</div>
<!-- END: CARD TV -->
<!-- BEGIN: CARD TUNER -->
<div id='card-1' data-title='Tuner' data-cmd-disabled='nec-4BB6D02F,nec-20DFA35C' style='display:none'>
<div class='row'>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4BB6D02F")'>
<span>AM / FM</span>
</button>
</div>
<div class='col-xs-4'></div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B36AA55")'>
<span>DISPLAY</span>
</button>
</div>
</div>
<div class='row'>
<!--vol +: 20DF40BF, vol -: 20DFC03F, mute: 20DF906F-->
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-4BB640BF")'>
<i class='glyphicon glyphicon-chevron-up'></i>
<br>
<span>Vol. +</span>
</button>
</div>
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-4BB600FF")'>
<i class='glyphicon glyphicon-chevron-up'></i>
<br>
<span>Prg. +</span>
</button>
</div>
</div>
<div class='row'>
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-4BB6C03F")'>
<i class='glyphicon glyphicon-chevron-down'></i>
<br>
<span>Vol. -</span>
</button>
</div>
<div class='col-xs-6'>
<button class='btn btn-primary' onclick='send("nec-4BB6807F")'>
<i class='glyphicon glyphicon-chevron-down'></i>
<br>
<span>Prg. -</span>
</button>
</div>
</div>
<hr>
<!-- KEYS -->
<div class='row'>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B40AB54")'>
<span>1</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B406B94")'>
<span>2</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B40EB14")'>
<span>3</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B401BE4")'>
<span>4</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B409B64")'>
<span>5</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B405BA4")'>
<span>6</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B40DB24")'>
<span>7</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B403BC4")'>
<span>8</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B40BB44")'>
<span>9</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B40FB04")'>
<span>D.TUN</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4B407B84")'>
<span>0</span>
</button>
</div>
<div class='col-xs-4'>
<button class='btn btn-xs btn-default' onclick='send("nec-4BB6BA45")'>
<span>SLEEP</span>
</button>
</div>
</div>
</div>
<!-- END: CARD TUNER -->
<!-- BEGIN: CARD TEST CODE -->
<div id='card-2' data-title='Test code' data-cmd-disabled='' style='display:none'>
<div class='row'>
<div class='col-xs-9'>
<span>
<select id='m' class='form-control'>
<option value='nec' selected>NEC</option>
<option value='rc5'>RC5</option>
<option value='rc6'>RC6</option>
</select>
</span>
<span>
<input type='text' id='c' value='20DFCA35' placeholder='code' class='form-control'>
</span>
<span>
<input type='text' id='b' value='32' placeholder='bits' class='form-control'>
</span>
<span>
<input type='text' id='r' value='1' placeholder='repeat' class='form-control'>
</span>
</div>
<div class='col-xs-3'>
<button class='btn btn-xs btn-default' onclick='sendTest()'>
<i class='glyphicon glyphicon-play'></i>
<br>
<span>Test</span>
</button>
</div>
</div>
</div>
<!-- END: CARD TEST -->
</div>
<!-- END: CONTAINER -->
e la parte
JavaScript/* libreria per swipe OMESSA */
/* main */
function getId(id) {
return document.getElementById(id)
}
/* gestione swipe - card */
var cardIndex = 0
, cardIndexMax = 2;
document.addEventListener('swiped-left', function(e) {
changeCard(1);
});
document.addEventListener('swiped-right', function(e) {
changeCard(-1);
});
function changeCard(moveIndex) {
cardIndex += moveIndex;
if (cardIndex < 0)
cardIndex = cardIndexMax;
else if (cardIndex > cardIndexMax)
cardIndex = 0;
showCard();
}
function showCard() {
/* card corrente */
var objCard = getId('card-' + cardIndex);
var title = objCard.getAttribute('data-title');
getId('title').innerText = title;
objCard.style.display = 'block';
/* next button */
var cardIndexNext = cardIndex >= cardIndexMax ? 0 : cardIndex + 1;
objCardNext = getId('card-' + cardIndexNext);
var titleNext = objCardNext.getAttribute('data-title');
getId('btn-tv-tuner').innerHTML = titleNext;
/* disattivo schede */
for (var i = 0; i <= cardIndexMax; i++) {
if (cardIndex !== i)
getId('card-' + i).style.display = 'none';
}
var cmd = objCard.getAttribute('data-cmd');
send(cmd);
}
;showCard();
/* test code */
function sendTest() {
var m = getId('m').value;
var c = getId('c').value;
var b = getId('b').value;
var r = getId('r').value;
sendFull(m, c, b, r);
}
/* invia comandi */
function send(cmds) {
if (cmds === null)
return;
var cmd = cmds.split(',');
for (var i = 0; i < cmd.length; i++) {
var m = ''
, c = ''
, b = null
, r = null;
var p = cmd[i].split('-');
if (p.length > 0)
m = p[0];
if (p.length > 1)
c = p[1];
if (p.length > 2)
b = p[2];
if (p.length > 3)
r = p[3];
sendFull(m, c, b, r);
}
}
function sendFull(m, c, b, r) {
try {
if (b === undefined || b == null || b === '' || b <= 0)
b = 32;
if (r === undefined || r == null || r === '' || r <= 0)
r = 1;
var url = '/ir?mode=' + m.toLowerCase() + '&code=0x' + c + '&bits=' + b + '&repeat=' + r + '&t=' + (new Date().getTime());
sendHttp(url);
} catch (e) {
console.log(e);
}
}
/* chiamata http */
function sendHttp(url) {
var loading = document.getElementById('loading');
loading.style.display = 'block';
try {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function() {
loading.style.display = 'none';
if (xhr.status === 200) {
console.log('OK');
} else {
alert('Error: ' + xhr.status);
}
}
;
xhr.onerror = function() {
loading.style.display = 'none';
alert("Errore nell'invio del codice");
}
;
xhr.send();
} catch (e) {
loading.style.display = 'none';
alert(e);
}
}
Modifica codici IR
Per modificare il codice inviato dei pulsanti, va cercato nel codice
HTML la chiamata alla funzione
JavaScript send(...) nell'evento
onclick.
Questo è un esempio realativo al tasto
mute<button class='btn btn-xs btn-default' onclick='send("nec-4BB6A05F")'>
<i class='glyphicon glyphicon-volume-off'></i>
<br>
<span>Mute</span>
</button>
La funzione
send è quella che chiama l'API (/if) per l'invio dei codici a infrarosso.
Macro
La funzione supporta anche le
macro, ovvero la possibilità di inviare più codici in sequenza.
Ad esempio per accendere
contemporaneamente sia il televisore che il decoder.
Per far questo è sufficiente separare i codici con una virgola
<button class='btn btn-xs btn-default' onclick='send("nec-20DF10EF,nec-4B36D32C")'>
Non lasciare spazi tra un codice e l'altro.