2018-07-09 22:04:36 +00:00
|
|
|
|
|
|
|
#include <IRremoteESP8266/src/IRremoteESP8266.h>
|
|
|
|
#include <IRremoteESP8266/src/IRsend.h>
|
|
|
|
#include <IRremoteESP8266/src/IRrecv.h>
|
|
|
|
#include <IRremoteESP8266/src/IRutils.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <ESP8266WiFi.h>
|
|
|
|
#include <PubSubClient.h>
|
2018-07-19 19:51:40 +00:00
|
|
|
#include <EEPROM.h>
|
2018-07-09 22:04:36 +00:00
|
|
|
//#include <IRremoteESP8266/src/>
|
|
|
|
#define IRLED_PIN 4
|
|
|
|
#define RECV_PIN 5
|
|
|
|
#define TOPIC "foobar/aerie/lounge/hifi"
|
|
|
|
// Update these with values suitable for your network.
|
|
|
|
|
|
|
|
const char* ssid = "foobar";
|
|
|
|
const char* password = "";
|
|
|
|
const char* mqtt_server = "10.42.0.244";
|
2018-07-19 19:51:40 +00:00
|
|
|
decode_results results;
|
2018-07-09 22:04:36 +00:00
|
|
|
|
|
|
|
IRsend irsend(IRLED_PIN);
|
|
|
|
IRrecv irrecv(RECV_PIN); //1024, 15U, true);
|
|
|
|
WiFiClient espClient;
|
|
|
|
PubSubClient client(espClient);
|
2018-07-19 19:51:40 +00:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
/* 501 bytes for 20 commands */
|
|
|
|
uint32_t codes[20];
|
|
|
|
char commands[20][20];
|
|
|
|
uint8_t command_lengths[20];
|
|
|
|
uint8_t size;
|
|
|
|
|
|
|
|
} storage;
|
|
|
|
|
|
|
|
storage store;
|
|
|
|
|
|
|
|
int deleteCommand(char * command, uint8_t length){
|
|
|
|
if (length < 20 && store.size > 1){
|
|
|
|
for ( uint8_t i = 0 ; i < store.size ; i++){
|
|
|
|
if ( strncmp(command, store.commands[i], length ) == 0){
|
|
|
|
memcpy( store.commands[i], store.commands[store.size], store.command_lengths[store.size]);
|
|
|
|
store.command_lengths[i] = store.command_lengths[store.size];
|
|
|
|
store.codes[i] = store.codes[store.size];
|
|
|
|
store.size--;
|
|
|
|
saveStore();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int saveCommand(char * command, uint8_t length, uint32_t code){
|
|
|
|
if ( length < 20){
|
|
|
|
memcpy( store.commands[store.size], command, length );
|
|
|
|
store.command_lengths[store.size] = length;
|
|
|
|
store.codes[store.size] = code;
|
|
|
|
store.size++;
|
|
|
|
saveStore();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int saveStore(){
|
2018-07-21 17:11:32 +00:00
|
|
|
EEPROM.begin(512); // 4096 Possible
|
2018-07-19 19:51:40 +00:00
|
|
|
EEPROM.put( 0, store ); // address of begin of eeprom "0"
|
|
|
|
delay(200);
|
|
|
|
EEPROM.commit(); // Only needed for ESP8266 to get data written
|
|
|
|
EEPROM.end(); // Free RAM copy of structure
|
|
|
|
}
|
|
|
|
|
|
|
|
int loadStore(){
|
|
|
|
EEPROM.begin(512);
|
|
|
|
EEPROM.get(0, store);
|
|
|
|
EEPROM.end();
|
|
|
|
}
|
2018-07-09 22:04:36 +00:00
|
|
|
|
|
|
|
void setup_wifi() {
|
|
|
|
|
|
|
|
delay(10);
|
|
|
|
// We start by connecting to a WiFi network
|
|
|
|
Serial.println();
|
|
|
|
Serial.print("Connecting to ");
|
|
|
|
Serial.println(ssid);
|
|
|
|
|
|
|
|
WiFi.begin(ssid, password);
|
|
|
|
|
|
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
|
|
delay(500);
|
|
|
|
Serial.print(".");
|
|
|
|
}
|
|
|
|
|
|
|
|
Serial.println("Connected!");
|
|
|
|
|
|
|
|
randomSeed(micros());
|
|
|
|
/*
|
|
|
|
Serial.println("");
|
|
|
|
Serial.println("WiFi connected");
|
|
|
|
Serial.println("IP address: ");
|
|
|
|
Serial.println(WiFi.localIP());
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
int check(char * buf, int length){
|
|
|
|
char * a = buf;
|
|
|
|
for (;a-buf < length;a++){
|
|
|
|
Serial.println(a);
|
|
|
|
if (*a >= 58 || *a <= 47)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int checkHex(char * buf, int length){
|
|
|
|
char * a = buf;
|
|
|
|
for (;a-buf < length;a++){
|
|
|
|
//Serial.println(a);
|
|
|
|
if (!(*a < 58 && *a > 47 || *a > 64 && *a < 71 || *a > 96 && *a < 103))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void callback(char* topic, byte* p, unsigned int length) {
|
|
|
|
char *payload = (char *)p;
|
|
|
|
|
|
|
|
if ( length >= 6 ){
|
|
|
|
|
|
|
|
if ( strncmp(payload, "beamer", 6) == 0){
|
|
|
|
irsend.sendNEC(0x5ea1936cUL,32);
|
|
|
|
}
|
|
|
|
if ( strncmp(payload, "lauter", 6) == 0){
|
|
|
|
irsend.sendNEC(0x5EA158A7UL,32);
|
|
|
|
}
|
|
|
|
if ( strncmp(payload, "leiser", 6) == 0){
|
|
|
|
irsend.sendNEC(0x5EA1D827UL,32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( length >= 7 ){
|
|
|
|
if ( strncmp(payload, "standby", 7) == 0){
|
|
|
|
irsend.sendNEC(0x7E81FE01UL,32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( length >= 5 ){
|
|
|
|
if ( strncmp(payload, "power", 5) == 0){
|
|
|
|
irsend.sendNEC(0x7e817e81UL,32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( length >= 3 ){
|
|
|
|
if ( strncmp(payload, "dvd", 3) == 0){
|
|
|
|
irsend.sendNEC(0x5ea1837cUL,32);
|
|
|
|
}
|
|
|
|
if ( strncmp(payload, "mpd", 3) == 0){
|
|
|
|
irsend.sendNEC(0x5ea1c837UL, 32);
|
|
|
|
}
|
|
|
|
if ( strncmp(payload, "dtv", 3) == 0){
|
|
|
|
irsend.sendNEC(0x5ea12ad5UL,32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-19 19:51:40 +00:00
|
|
|
if ( store.size > 0){
|
|
|
|
for ( uint8_t i = 0; i < store.size; i++){
|
|
|
|
if (strncmp(payload, store.commands[i], store.command_lengths[i]) == 0){
|
|
|
|
irsend.sendNEC(store.codes[i],32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( length > 16 && strncmp(payload, "record:", 7) == 0){ //record:command:code
|
|
|
|
//Serial.println("Custom0");
|
|
|
|
char * a = payload + 7;
|
|
|
|
char command[20];
|
|
|
|
uint8_t length = 0;
|
|
|
|
uint32_t code = 0;
|
|
|
|
memcpy(command, NULL, 20);
|
|
|
|
int i = 0;
|
|
|
|
for ( ; i < 20; i++ ){
|
|
|
|
if (*(a+i) == ':'){
|
|
|
|
memcpy(command, a, i);
|
|
|
|
length = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( checkHex(a+i+1,8) ){
|
|
|
|
char *start = a+1+i;
|
|
|
|
char *end = a+i+8;
|
|
|
|
*(end+1) = ' ';
|
|
|
|
code = strtoul(start,&end,16);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( code != 0 && length != 0){
|
|
|
|
if ( saveCommand(command, length, code) == 0 ){
|
|
|
|
char buff[35];
|
|
|
|
char * pos = buff;
|
|
|
|
pos += sprintf(pos, "%s","Added command: ");
|
|
|
|
pos += sprintf(pos, "%s", command);
|
|
|
|
client.publish(TOPIC, buff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( length > 16 && strncmp(payload, "delete:", 7) == 0){ //delete:comamnd:
|
|
|
|
//Serial.println("Custom0");
|
|
|
|
char * a = payload + 7;
|
|
|
|
char command[20];
|
|
|
|
uint8_t length = 0;
|
|
|
|
memcpy(command, NULL, 20);
|
|
|
|
int i = 0;
|
|
|
|
for ( ; i < 20; i++ ){
|
|
|
|
if (*(a+i) == ':'){
|
|
|
|
memcpy(command, a, i);
|
|
|
|
length = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( length > 0 ){
|
|
|
|
if (deleteCommand(command, length) == 0){
|
|
|
|
char buff[37];
|
|
|
|
char * pos = buff;
|
|
|
|
pos += sprintf(pos, "%s","deleted command: ");
|
|
|
|
pos += sprintf(pos, "%s", command);
|
|
|
|
client.publish(TOPIC, buff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( length > 11 && strncmp(payload, "nec:", 4) == 0){
|
2018-07-09 22:04:36 +00:00
|
|
|
//Serial.println("Custom0");
|
|
|
|
if ( checkHex(payload+4, 8)){
|
|
|
|
char *start = payload + 4;
|
|
|
|
char *end = payload + 7 + 4;
|
|
|
|
*(end+1) = ' ';
|
|
|
|
unsigned int nec_code = strtoul (start, &end, 16);
|
|
|
|
irsend.sendNEC(nec_code, 32);
|
|
|
|
char buff[20];
|
|
|
|
char * pos = buff;
|
|
|
|
Serial.println(nec_code);
|
|
|
|
pos += sprintf(pos, "%s","Sent NEC Code: ");
|
|
|
|
pos += sprintf(pos, "%X", nec_code);
|
|
|
|
Serial.println(buff);
|
|
|
|
client.publish(TOPIC, buff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void reconnect() {
|
|
|
|
while (!client.connected()) {
|
|
|
|
String clientId = "HIFI LOUNGE CTRL";
|
|
|
|
clientId += String(random(0xffff), HEX);
|
|
|
|
if (client.connect(clientId.c_str())) {
|
|
|
|
client.publish(TOPIC, "HIFI Control Online");
|
|
|
|
client.subscribe(TOPIC);
|
|
|
|
} else {
|
|
|
|
delay(5000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
pinMode(IRLED_PIN, OUTPUT);
|
|
|
|
digitalWrite(IRLED_PIN, LOW); // Turn the LED on (Note that LOW is the voltage level// Initialize the BUILTIN_LED pin as an output
|
|
|
|
Serial.begin(115200);
|
|
|
|
setup_wifi();
|
|
|
|
client.setServer(mqtt_server, 1883);
|
|
|
|
client.setCallback(callback);
|
|
|
|
irrecv.enableIRIn(); // Start the receiver
|
2018-07-19 19:51:40 +00:00
|
|
|
loadStore();
|
2018-07-09 22:04:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
|
|
|
if (!client.connected()) {
|
|
|
|
reconnect();
|
|
|
|
}
|
|
|
|
client.loop();
|
|
|
|
|
|
|
|
if (irrecv.decode(&results)) {
|
|
|
|
Serial.println("entered irrecv decoding phase");
|
|
|
|
if (results.overflow){
|
|
|
|
client.publish(TOPIC, "Parsing failed!");
|
|
|
|
} else {
|
|
|
|
char msg_buf[51] = "32bit Representation NEC Code:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
|
|
|
itoa(results.value, (msg_buf+30), 16);
|
|
|
|
serialPrintUint64(results.value, HEX);
|
|
|
|
client.publish(TOPIC, msg_buf);
|
|
|
|
}
|
|
|
|
irrecv.resume();
|
|
|
|
}
|
|
|
|
}
|
2018-07-19 19:51:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
7e81fe01 standby
|
|
|
|
7e817e81 power
|
|
|
|
5ea1c837 dvr
|
|
|
|
5ea1936c md/cd-r
|
|
|
|
5ea16897 tuner
|
|
|
|
5ea1e11e multi channel in
|
|
|
|
Code:5ea1837c dvd
|
|
|
|
Code:5ea12ad5 dtv
|
|
|
|
*/
|