Основной скетч управления.
File - wifitvpult.ino
#include <FS.h>
#include <LittleFS.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
#define DEBUG
#define DEBUG_WS
#include <ESP8266HTTPClient.h>
#include "4duk.h"
#include "WebSocketClient.h"
#include "fsio.h"
#define SSDP_MCAST 239,255,255,250
#define SSDP_PORT 1900
#define STASSID "MYWIFI"
#define STAPSK "topsecret"
long timezone = 2;
byte daysavetime = 1;
unsigned char buf[2048];
char g_id[128]="i000000000000000000000000000000d";
char room[128]="Настроечная";
char prod[128]="Alex Software";
char mail[128]="alex@ilona.su";
char d_name[128];
char a_name[128];
const char sony_remote_js[]="http://4duk.ilona.su/staticdownload/esp8266/sonyremote.js";
const char sony_js[]="/sonyremote.js";
const char root_page_b[] = "<html><head>\
<meta charset=\"utf8\">\
<title>Пульт TV</title>\
</head>\
<body>\
<h1>Пульт TV</h1>\
<a href=\"/updatetvs\">Обновить список телевизоров</a>\
<br>";
const char root_page_e[]="<form>IP address TV<input id=\"tvip\" type=\"text\">\
</form><br>\
<button onclick=\"sendcommand(\'test\');\">ON</button>\
<button>OFF</button>\
<script type=\"text/javascript\" src=\"/sonyremote.js\"></script>\
</body></html>";
gate4duk gate;
WiFiUDP Udp;
IPAddress ip_mcast(SSDP_MCAST);
IPAddress bcast;
String mmc;
IPAddress mip;
char buffer[2048];
ESP8266WebServer HTTP(80);
char gateid[128];
char mdns_name[]="PULT4DUK";
bool is_rcmd;
String r_cmd;
static void proci_cmd(String pp_cmd) {
is_rcmd=true;
r_cmd=pp_cmd;
r_cmd.replace("\n","");
r_cmd.replace("\r","");
}
static void proca_cmd(String pp_cmd) {
String p_cmd=pp_cmd;
p_cmd.replace("\n","");
Serial.println(p_cmd);
String f_s="device:tv";
if (p_cmd.indexOf(f_s)>-1) {
String ss_mac=p_cmd.substring(p_cmd.indexOf("device:tv")+9,p_cmd.indexOf(":",p_cmd.indexOf("device:tv")+9));
Serial.printf("Raw mac %s\n",ss_mac.c_str());
String s_mac=String(ss_mac.substring(0,2)+String(":")+ss_mac.substring(2,4)+String(":")+ss_mac.substring(4,6)+String(":")+ss_mac.substring(6,8)+String(":")+ss_mac.substring(8,10)+String(":")+ss_mac.substring(10,12));
Serial.printf("Detected mac %s\n",s_mac.c_str());
Serial.printf("From Alice Send %s to %s\n",p_cmd.c_str(),s_mac.c_str());
if (p_cmd.indexOf("action:on_off:value:on")>-1) {
//Serial.println("ALICE POWERON");
tv_ctl(String(s_mac+"-POWERON"));
} else if (p_cmd.indexOf("action:on_off:value:off")>-1) {
tv_ctl(String(s_mac+"-POWEROFF"));
} else if (p_cmd.indexOf("action:volume:value:+")>-1) {
tv_ctl(String(s_mac+"-VOLUP"));
} else if (p_cmd.indexOf("action:volume:value:-")>-1) {
tv_ctl(String(s_mac+"-VOLDOWN"));
} else if (p_cmd.indexOf("action:volume:")>-1) {
String s_l=p_cmd.substring(p_cmd.indexOf("value:")+6);
tv_ctl(String(s_mac+"-SETVOL "+s_l));
} else if (p_cmd.indexOf("action:channel:value:+")>-1) {
tv_ctl(String(s_mac+"-CHANUP"));
} else if (p_cmd.indexOf("action:channel:value:-")>-1) {
tv_ctl(String(s_mac+"-CHANDOWN"));
} else if (p_cmd.indexOf("action:channel:")>-1) {
String s_l=p_cmd.substring(p_cmd.indexOf("value:")+6);
tv_ctl(String(s_mac+"-SETCHAN "+s_l));
} else if (p_cmd.indexOf("action:input_source:value:1")>-1) {
tv_ctl(String(s_mac+"-TV"));
} else if (p_cmd.indexOf("action:input_source:value:2")>-1) {
tv_ctl(String(s_mac+"-HDMI"));
} else if (p_cmd.indexOf("action:input_source:value:3")>-1) {
tv_ctl(String(s_mac+"-AV"));
} else if (p_cmd.indexOf("action:mute:")>-1) {
tv_ctl(String(s_mac+"-MUTE"));
}
}
}
String proca_stat(String p_cmd) {
Serial.println(p_cmd);
String $tv_mac_raw=p_cmd.substring(p_cmd.indexOf("tv")+2,p_cmd.indexOf(":",p_cmd.indexOf("tv")+2));
String $tv_mac=$tv_mac_raw.substring(0,2)+":"+$tv_mac_raw.substring(2,4)+":"+$tv_mac_raw.substring(4,6)+":"+$tv_mac_raw.substring(6,8)+":"+$tv_mac_raw.substring(8,10)+":"+$tv_mac_raw.substring(10,12);
if (LittleFS.exists(String($tv_mac+".on"))) {
return p_cmd+"on_off:on";
} else {
return p_cmd+"on_off:off";
}
return p_cmd;
}
//handles for HTTP
void handleNotFound() {
String s_uri=HTTP.uri();
String o_m;
s_uri=s_uri.substring(1);
if (s_uri.indexOf("/rctv")>-1) {
//o_m=show_rctv(HTTP.arg(0));
HTTP.send(200, "text/plain", o_m);
} else if (LittleFS.exists(s_uri.c_str())) {
if ((s_uri.indexOf(".dsc")>-1) && (s_uri.indexOf(".dsc/")==-1)) {
HTTP.send(200, "text/html", listDir(WiFi.localIP().toString(),s_uri));
} else if (s_uri.indexOf(".html")>-1) {
File html=LittleFS.open(s_uri.c_str(),"r");
HTTP.stream(html,"text/html");
html.close();
} else if (s_uri.indexOf(".js")>-1) {
File js=LittleFS.open(s_uri.c_str(),"r");
HTTP.stream(js,"application/javascript");
js.close();
} else {
File txt=LittleFS.open(s_uri.c_str(),"r");
HTTP.stream(txt,"text/plain");
txt.close();
}
} else {
String message = "File Not Found\n\n";
message += "URI: ";
message += HTTP.uri();
message += "\nMethod: ";
message += (HTTP.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += HTTP.args();
message += "\n";
for (uint8_t i = 0; i < HTTP.args(); i++) { message += " " + HTTP.argName(i) + ": " + HTTP.arg(i) + "\n"; }
HTTP.send(404, "text/plain", message);
Serial.println(message);
}
}
void tvcontrol() {
if (HTTP.method() == HTTP_POST) {
String a1=HTTP.arg("plain");
Serial.println("Get name 0 "+a1);
HTTP.send(200,"text/plain",a1);
//tv_up(a1);
tv_ctl(a1);
} else {
HTTP.send(404, "text/plain", "Denied");
}
}
void waketv() {
if (HTTP.method() == HTTP_POST) {
String a1=HTTP.arg("plain");
Serial.println("Get name 0 "+a1);
HTTP.send(200,"text/plain",a1);
tv_up(a1);
} else {
HTTP.send(404, "text/plain", "Denied");
}
}
void deletetv() {
if (HTTP.method() == HTTP_POST) {
String a1=HTTP.arg("plain");
Serial.println("Get name 0 "+a1);
HTTP.send(200,"text/plain",a1);
removetv(a1);
} else {
HTTP.send(404, "text/plain", "Denied");
}
}
void gettvvolume() {
if (HTTP.method() == HTTP_POST) {
String a1=HTTP.arg("plain");
Serial.println("Get name 0 "+a1);
HTTP.send(200,"text/plain",gtvvol(a1));
//gtvvol(a1);
} else {
HTTP.send(404, "text/plain", "Denied");
}
}
void addth() {
if (HTTP.method() == HTTP_POST) {
String a1=HTTP.arg("plain");
Serial.println("Get name 0 "+a1);
HTTP.send(200,"text/plain",a1);
tvtoth(a1);
} else {
HTTP.send(404, "text/plain", "Denied");
}
}
void handleRoot() {
String root_page=String(root_page_b)+getlistth()+String(root_page_e);
HTTP.send(200,"text/html",root_page);
}
void updatetvs() {
parse_tvs();
String p_head="<html><head><meta charset=\"utf8\"><title>Обновлено</title></head><body><h1>Список телевизоров</h1><br>";
String p_foot="</body></html>";
String all=p_head+String("Обновлено.<a href=\"/\">На главную</a>")+p_foot;
HTTP.send(200,"text/html",all);
}
void listtv() {
String p_head="<html><head><meta charset=\"utf8\"><title>Список телевизоров</title></head><body><h1>Список телевизоров</h1><br>";
String p_foot="</body></html>";
String p_body="";
HTTP.send(200,"text/html",p_head+listtvname("")+p_foot);
}
void hlistDir() {
String pc=listDir(WiFi.localIP().toString(),"/");
HTTP.send(200,"text/html",pc);
}
void handlejsload() {
File file = LittleFS.open(sony_js, "r");
HTTP.streamFile(file, "text/javascript");
file.close();
}
void setup() {
r_cmd=false;
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.println("Boot");
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
Serial.println(WiFi.broadcastIP());
bcast=WiFi.broadcastIP();
mip=WiFi.localIP();
mmc=WiFi.macAddress();
mmc.replace(":","");
configTime(3600 * timezone, daysavetime * 3600, "0.pool.ntp.org", "1.pool.ntp.org");
struct tm tmstruct;
delay(2000);
tmstruct.tm_year = 0;
getLocalTime(&tmstruct, 5000);
Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
Udp.beginMulticast(WiFi.localIP(),ip_mcast,SSDP_PORT);
HTTP.on("/", handleRoot);
HTTP.on("/sonyremote.js", handlejsload);
HTTP.on("/listtv", listtv);
HTTP.on("/waketv", waketv);
HTTP.on("/deletetv", deletetv);
HTTP.on("/tvcommand", tvcontrol);
HTTP.on("/tvtoth", addth);
HTTP.on("/ls", hlistDir);
HTTP.on("/getvolume", gettvvolume);
HTTP.on("/updatetvs", updatetvs);
HTTP.onNotFound(handleNotFound);
HTTP.begin();
if (!LittleFS.begin()) {
Serial.println("LittleFS mount failed. Formatting...");
LittleFS.format();
}
if (!LittleFS.begin()) {
Serial.println("LittleFS remount failed.");
}
download_sfile("https://4duk.su/downloads/tvremote/esp8266/sonyremote.js","sonyremote.js",false);
download_sfile("https://4duk.su/downloads/tvremote/esp8266/tvcontrol.js","tvcontrol.js",false);
//download_sfile("https://4duk.su/downloads/tvremote/esp8266/tvcontrol.html","tvcontrol.html",false);
download_sfile("https://4duk.su/downloads/tvremote/esp8266/tvcontrol1.html","tvcontrol1.html",false);
download_sfile("https://4duk.su/downloads/tvremote/esp8266/tvcontrol2.html","tvcontrol2.html",false);
download_sfile("https://4duk.su/idgate?inpip="+mip.toString()+",mac="+mmc,"gateid.txt",false);
if (LittleFS.exists("gateid.txt")) {
File ff=LittleFS.open("gateid.txt","r");
uint8_t gg_id[128];
int rr=ff.read(gg_id,80);
gg_id[rr]=0;
ff.close();
for (int i=0;i<=rr;i++) {
g_id[i]=gg_id[i];
}
//strncpy(g_id,gg_id,rr);
}
gate.setid(g_id);
gate.setname(mdns_name);
gate.setbcast(bcast);
gate.connect(true);
Dir rr=LittleFS.openDir("");
while (rr.next()) {
String rr_fn=rr.fileName();
if (rr_fn.indexOf(".th")>-1) {
String p_mac=rr_fn.substring(0,rr_fn.indexOf(".th"));
String n_mac=getFile(String("/"+p_mac+".macname").c_str());
p_mac.replace(":","");
//p_mac="tv"+p_mac;
//n_mac="TV-"+n_mac;
sprintf(d_name,"tv%s",p_mac.c_str());
sprintf(a_name,"TV %s",n_mac.c_str());
//const char room[]="Настроечная";
//const char mail[]="slex@ilona.su";
//const char prod[]="Alex Software";
//gate.addrealdev(DEV_MEDIA_DEVICE_TV,p_mac,n_mac,"Настроечная","Alex Software","alex@ilona.su",0.1,proca_cmd,proca_stat);
Serial.printf("Add device %s,%s\n",d_name,a_name);
gate.addrealdev(DEV_MEDIA_DEVICE_TV,d_name,a_name,room,prod,mail,0.1,proci_cmd,proca_stat);
//download_sfile("https://4duk.su/idgate?adddev=yes,mac="+mmc+",dtype="+String(DEV_MEDIA_DEVICE_TV).toInt()+",dname="+d_name+",aname="+a_name,String(p_mac+".txt"),false);
}
}
}
void loop() {
// put your main code here, to run repeatedly:
int plen=0;
int i;
if (!gate.is_connected()) {
gate.reconnect(true);
}
gate.processmqtt();
gate.processudp();
if (Udp.available()>0) {
plen=Udp.parsePacket();
memset(buffer,0,2048);
Udp.read(buffer,2048);
buffer[plen]=0;
String bb=String(buffer);
if (bb.indexOf("ssdp:alive")>0) {
Serial.print("Add ");
Serial.println(Udp.remoteIP());
int pos_loc=bb.indexOf("http://");
int pos_loc_end=bb.indexOf("\r\n",pos_loc);
String loc_url_avtransport=bb.substring(pos_loc,pos_loc_end);
Serial.print("==");
Serial.print(loc_url_avtransport);
Serial.println("==");
get_url_content(loc_url_avtransport);
String rip="/"+Udp.remoteIP().toString()+".url";
String d_mac=get_mac(Udp.remoteIP().toString());
writeFile(String("/"+d_mac+".macip").c_str(),Udp.remoteIP().toString().c_str());
writeFile(String("/"+Udp.remoteIP().toString()+".ipmac").c_str(),d_mac.c_str());
writeFile(String("/"+d_mac+".on").c_str(),"0");
writeFile(String("/"+Udp.remoteIP().toString()+".on").c_str(),"0");
if (bb.indexOf(":service:")>-1) {
if (!LittleFS.exists(String(d_mac+".dsc").c_str())) {
if(!LittleFS.mkdir(String(d_mac+".dsc").c_str())) {
Serial.printf("Error create %s\n",String(d_mac+".dsc").c_str());
}
}
String s_service=bb.substring(bb.indexOf(":service:")+9,bb.indexOf("\r\n",bb.indexOf(":service:")+9));
if (s_service.length()>30) {
s_service=s_service.substring(0,30);
}
writeFile(String(d_mac+".dsc/"+s_service).c_str(),loc_url_avtransport.c_str());
}
} else if (bb.indexOf("ssdp:byebye")>0) {
Serial.print("Remove ");
Serial.println(Udp.remoteIP());
String mac_ip=getFile(String(String(Udp.remoteIP().toString())+".ipmac").c_str());
LittleFS.remove(String(mac_ip+".on").c_str());
LittleFS.remove(String(String(Udp.remoteIP().toString())+".on").c_str());
} else {
//Serial.print(plen);
//Serial.print(" ");
//Serial.println(bb);
}
Udp.flush();
Udp.stop();
Udp.beginMulticast(WiFi.localIP(),ip_mcast,SSDP_PORT);
} else {
delay(50);
}
if (is_rcmd) {
is_rcmd=false;
proca_cmd(r_cmd);
}
gate.sendstatus();
//delay(1000);
//Serial.println("Step .");
HTTP.handleClient();
MDNS.update();
delay(2000);
}