I have a TV and Rasberry Pi set up for media. The sound system is an AV AMP plus powered Sub and 7 active speakers. To power these units on and off I had used nine 433Mhz Remote plugs.
This worked well for the most part but sometime the 433Mhz remote would not always power on / off all the devices and the remote was cheap, plus it meant another remote to deal with.
I used a Wemos D1 Mini (ESP8266 based unit) and a cheap 433mHz transmitter: +3.3V to VCC, GND to GND and Data to GPIO0 which is pin D3 with the sketch below its a web server that waits for ON or OFF requests and then outputs the appropriate 433mHz command.
On the Kodi server (Rasberry Pi 2) I created a couple of scripts containing these command. The -O option stops wget writing the output to a file and pipes the response from the server to null
System.Exec("/storage/off.sh")
/*
ESP8266 mDNS responder sample
This is an based on an example of an HTTP server that is accessible
via http://esp8266.local URL thanks to mDNS responder.
Instructions:
- Update WiFi SSID and password as necessary.
- Flash the sketch to the ESP8266 board
- Install host software:
- For Linux, install Avahi (http://avahi.org/).
- For Windows, install Bonjour (http://www.apple.com/support/bonjour/).
- For Mac OSX and iOS support is built in through Bonjour already.
- Point your browser to http://esp8266.local, you should see a response.
*/
#include
#include
#include
#include
RCSwitch mySwitch = RCSwitch();
const char* ssid = "mywifi";
const char* password = "secret";
// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);
void setup(void)
{
//Serial.begin(115200);
Serial.begin(9600);
mySwitch.enableTransmit(0);
/* AV On
* Decimal: 2727773 (24Bit) Binary: 001010011001111101011101 Tri-State: not applicable PulseLength: 306 microseconds Protocol: 1
* Raw data: 9556,292,912,292,916,892,312,296,920,888,308,296,944,264,936,876,316,888,320,280,940,272,924,880,304,900,312,892,320,880,324,888,312,292,952,856,332,276,944,864,324,880,336,868,332,272,956,856,372,
* AV Off
* Decimal: 2727765 (24Bit) Binary: 001010011001111101010101 Tri-State: not applicable PulseLength: 307 microseconds Protocol: 1
* Raw data: 9564,284,916,292,920,888,308,296,928,880,312,296,924,284,916,892,308,904,308,292,916,288,920,892,312,892,316,892,316,892,312,896,316,280,948,864,320,288,948,856,324,280,952,860,324,284,944,864,356, */
// Set protocol (default is 1, will work for most outlets)
mySwitch.setProtocol(1);
// Set pulse length.
mySwitch.setPulseLength(306);
// Optional set number of transmission repetitions.
mySwitch.setRepeatTransmit(7);
// Connect to WiFi network
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Set up mDNS responder:
// - first argument is the domain name, in this example
// the fully-qualified domain name is "esp8266.local"
// - second argument is the IP address to advertise
// we send our IP address on the WiFi network
if (!MDNS.begin("esp8266")) {
Serial.println("Error setting up MDNS responder!");
while(1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
// Start TCP (HTTP) server
server.begin();
Serial.println("TCP server started");
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 80);
}
void loop(void)
{
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("");
Serial.println("New client");
// Wait for data from client to become available
while(client.connected() && !client.available()){
delay(1);
}
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
client.flush();
String s="";
if (req == "/")
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nHello from ESP8266 at ";
s += ipStr;
s += "
\r\n\r\n"; Serial.println("Sending 200");
}
if (req == "/ON")
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nON from ESP8266 at ";
s += ipStr;
s += "
\r\n\r\n"; Serial.println("Sending 200");
Serial.println("Power On \n");
/* Added repeata, even though the initial Tx has repeats
waiting for 2s and resending catches the eddge cases
In my set up I have thousands of Watts of power amps,
dedicated powers subs and a large plasma display all powering up
This creates a large amount of RFI. The problem is compound by large metal
speaker stands mounted on the wall near the dedicated power sockets
all mounted in the wall.*/
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
}
if (req == "/OFF")
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nOFF from ESP8266 at ";
s += ipStr;
s += "
\r\n\r\n"; Serial.println("Sending 200");
Serial.println("Power Off\n");
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
}
if (s=="")
{
s = "HTTP/1.1 404 Not Found\r\n\r\n";
Serial.println("Sending 404");
}
client.print(s);
Serial.println("Done with client");
}
This worked well for the most part but sometime the 433Mhz remote would not always power on / off all the devices and the remote was cheap, plus it meant another remote to deal with.
I used a Wemos D1 Mini (ESP8266 based unit) and a cheap 433mHz transmitter: +3.3V to VCC, GND to GND and Data to GPIO0 which is pin D3 with the sketch below its a web server that waits for ON or OFF requests and then outputs the appropriate 433mHz command.
On the Kodi server (Rasberry Pi 2) I created a couple of scripts containing these command. The -O option stops wget writing the output to a file and pipes the response from the server to null
- wget http://192.168.0.218/OFF -O /dev/null
- wget http://192.168.0.218/ON -O /dev/null
Then on the Rasberry Pi running LibreElec I create a this file /storage/.kodi/userdata/keymaps/gen.xml to link the scripts to button on the remote. In this case p and o to the power on and off respectively.
Remember to chmod +x the script files so you have execute permission.
System.Exec("/storage/on.sh")
This is the web server program.
ESP8266 mDNS responder sample
This is an based on an example of an HTTP server that is accessible
via http://esp8266.local URL thanks to mDNS responder.
Instructions:
- Update WiFi SSID and password as necessary.
- Flash the sketch to the ESP8266 board
- Install host software:
- For Linux, install Avahi (http://avahi.org/).
- For Windows, install Bonjour (http://www.apple.com/support/bonjour/).
- For Mac OSX and iOS support is built in through Bonjour already.
- Point your browser to http://esp8266.local, you should see a response.
*/
#include
#include
#include
#include
RCSwitch mySwitch = RCSwitch();
const char* ssid = "mywifi";
const char* password = "secret";
// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);
void setup(void)
{
//Serial.begin(115200);
Serial.begin(9600);
mySwitch.enableTransmit(0);
/* AV On
* Decimal: 2727773 (24Bit) Binary: 001010011001111101011101 Tri-State: not applicable PulseLength: 306 microseconds Protocol: 1
* Raw data: 9556,292,912,292,916,892,312,296,920,888,308,296,944,264,936,876,316,888,320,280,940,272,924,880,304,900,312,892,320,880,324,888,312,292,952,856,332,276,944,864,324,880,336,868,332,272,956,856,372,
* AV Off
* Decimal: 2727765 (24Bit) Binary: 001010011001111101010101 Tri-State: not applicable PulseLength: 307 microseconds Protocol: 1
* Raw data: 9564,284,916,292,920,888,308,296,928,880,312,296,924,284,916,892,308,904,308,292,916,288,920,892,312,892,316,892,316,892,312,896,316,280,948,864,320,288,948,856,324,280,952,860,324,284,944,864,356, */
// Set protocol (default is 1, will work for most outlets)
mySwitch.setProtocol(1);
// Set pulse length.
mySwitch.setPulseLength(306);
// Optional set number of transmission repetitions.
mySwitch.setRepeatTransmit(7);
// Connect to WiFi network
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Set up mDNS responder:
// - first argument is the domain name, in this example
// the fully-qualified domain name is "esp8266.local"
// - second argument is the IP address to advertise
// we send our IP address on the WiFi network
if (!MDNS.begin("esp8266")) {
Serial.println("Error setting up MDNS responder!");
while(1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
// Start TCP (HTTP) server
server.begin();
Serial.println("TCP server started");
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 80);
}
void loop(void)
{
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("");
Serial.println("New client");
// Wait for data from client to become available
while(client.connected() && !client.available()){
delay(1);
}
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
client.flush();
String s="";
if (req == "/")
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nHello from ESP8266 at ";
s += ipStr;
s += "
\r\n\r\n"; Serial.println("Sending 200");
}
if (req == "/ON")
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nON from ESP8266 at ";
s += ipStr;
s += "
\r\n\r\n"; Serial.println("Sending 200");
Serial.println("Power On \n");
/* Added repeata, even though the initial Tx has repeats
waiting for 2s and resending catches the eddge cases
In my set up I have thousands of Watts of power amps,
dedicated powers subs and a large plasma display all powering up
This creates a large amount of RFI. The problem is compound by large metal
speaker stands mounted on the wall near the dedicated power sockets
all mounted in the wall.*/
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
mySwitch.send("001010011001111101011101"); // Button 3 On
delay(2000);
}
if (req == "/OFF")
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nOFF from ESP8266 at ";
s += ipStr;
s += "
\r\n\r\n"; Serial.println("Sending 200");
Serial.println("Power Off\n");
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
mySwitch.send("001010011001111101010101"); // Button 3 Off
delay(2000);
}
if (s=="")
{
s = "HTTP/1.1 404 Not Found\r\n\r\n";
Serial.println("Sending 404");
}
client.print(s);
Serial.println("Done with client");
}