diff --git a/src/cmnds/cmd_eventHandlers.c b/src/cmnds/cmd_eventHandlers.c index d08cacaa9..5e943606c 100644 --- a/src/cmnds/cmd_eventHandlers.c +++ b/src/cmnds/cmd_eventHandlers.c @@ -71,6 +71,11 @@ AddEventHandler OnClick 0 addChannel 1 -10 0 100 AddEventHandler OnClick 1 addCh // Event to fire on binary (hex) value received by TuyaMCU AddEventHandler OnUART 55AA00FF setChannel 0 1 + +// IR events +addEventHandler2 Samsung 0x707 0x68 setChannel 1 0 + + */ // @@ -129,6 +134,22 @@ static int EVENT_ParseEventName(const char *s) { return CMD_EVENT_CHANGE_CONSUMPTION_TOTAL; if(!stricmp(s,"energycounter_last_hour")) return CMD_EVENT_CHANGE_CONSUMPTION_LAST_HOUR; + if(!stricmp(s,"IR_RC5")) + return CMD_EVENT_IR_RC5; + if(!stricmp(s,"IR_RC6")) + return CMD_EVENT_IR_RC6; + if(!stricmp(s,"IR_Samsung")) + return CMD_EVENT_IR_SAMSUNG; + if(!stricmp(s,"IR_PANASONIC")) + return CMD_EVENT_IR_PANASONIC; + if(!stricmp(s,"IR_NEC")) + return CMD_EVENT_IR_NEC; + if(!stricmp(s,"IR_SAMSUNG_LG")) + return CMD_EVENT_IR_SAMSUNG_LG; + if(!stricmp(s,"IR_SHARP")) + return CMD_EVENT_IR_SHARP; + if(!stricmp(s,"IR_SONY")) + return CMD_EVENT_IR_SONY; return CMD_EVENT_NONE; } static bool EVENT_EvaluateCondition(int code, int argument, int next) { @@ -192,6 +213,7 @@ typedef struct eventHandler_s { // For example, you can do "addEventHandler OnClick 5" // and it will only fire for pin 5 short requiredArgument; + short requiredArgument2; // command to execute when it happens char *command; // for UART event handlers? @@ -219,7 +241,7 @@ void EventHandlers_ProcessVariableChange_Integer(byte eventCode, int oldValue, i } } -void EventHandlers_AddEventHandler_Integer(byte eventCode, int type, int requiredArgument, const char *commandToRun) +void EventHandlers_AddEventHandler_Integer(byte eventCode, int type, int requiredArgument, int requiredArgument2, const char *commandToRun) { eventHandler_t *ev = malloc(sizeof(eventHandler_t)); @@ -231,6 +253,7 @@ void EventHandlers_AddEventHandler_Integer(byte eventCode, int type, int require ev->command = test_strdup(commandToRun); ev->eventCode = eventCode; ev->requiredArgument = requiredArgument; + ev->requiredArgument2 = requiredArgument2; } void EventHandlers_AddEventHandler_String(byte eventCode, int type, const char *requiredArgument, const char *commandToRun) @@ -245,6 +268,22 @@ void EventHandlers_AddEventHandler_String(byte eventCode, int type, const char * ev->command = test_strdup(commandToRun); ev->eventCode = eventCode; ev->requiredArgument = 0; + ev->requiredArgument2 = 0; +} +void EventHandlers_FireEvent2(byte eventCode, int argument, int argument2) { + struct eventHandler_s *ev; + + ev = g_eventHandlers; + + while(ev) { + if(eventCode==ev->eventCode) { + if(argument == ev->requiredArgument && argument2 == ev->requiredArgument2) { + ADDLOG_INFO(LOG_FEATURE_EVENT, "EventHandlers_FireEvent2: executing command %s",ev->command); + CMD_ExecuteCommand(ev->command, COMMAND_FLAG_SOURCE_SCRIPT); + } + } + ev = ev->next; + } } void EventHandlers_FireEvent(byte eventCode, int argument) { struct eventHandler_s *ev; @@ -254,13 +293,12 @@ void EventHandlers_FireEvent(byte eventCode, int argument) { while(ev) { if(eventCode==ev->eventCode) { if(argument == ev->requiredArgument) { - ADDLOG_INFO(LOG_FEATURE_EVENT, "EventHandlers_ProcessVariableChange_Integer: executing command %s",ev->command); + ADDLOG_INFO(LOG_FEATURE_EVENT, "EventHandlers_FireEvent: executing command %s",ev->command); CMD_ExecuteCommand(ev->command, COMMAND_FLAG_SOURCE_SCRIPT); } } ev = ev->next; } - } void EventHandlers_FireEvent_String(byte eventCode, const char *argument) { struct eventHandler_s *ev; @@ -284,9 +322,11 @@ void EventHandlers_FireEvent_String(byte eventCode, const char *argument) { static int CMD_AddEventHandler(const void *context, const char *cmd, const char *args, int cmdFlags){ const char *eventName; int reqArg; + int arg2; const char *cmdToCall; int eventCode; const char *reqArgStr; + int bTwoArgsMode; if(args==0||*args==0) { ADDLOG_INFO(LOG_FEATURE_EVENT, "CMD_AddEventHandler: command requires argument"); @@ -297,6 +337,15 @@ static int CMD_AddEventHandler(const void *context, const char *cmd, const char ADDLOG_INFO(LOG_FEATURE_EVENT, "CMD_AddEventHandler: command requires 3 arguments"); return 1; } + if(cmd[strlen("addEventHandler2")-1]=='2') { + bTwoArgsMode = 1; + ADDLOG_INFO(LOG_FEATURE_EVENT, "CMD_AddEventHandler: will expect two args."); + } else { + bTwoArgsMode = 0; + ADDLOG_INFO(LOG_FEATURE_EVENT, "CMD_AddEventHandler: will expect 1 arg."); + } + + arg2 = 0; eventName = Tokenizer_GetArg(0); if(false==Tokenizer_IsArgInteger(1)) { @@ -305,8 +354,17 @@ static int CMD_AddEventHandler(const void *context, const char *cmd, const char } else { reqArgStr = 0; reqArg = Tokenizer_GetArgInteger(1); + if(bTwoArgsMode) { + arg2 = Tokenizer_GetArgInteger(2); + ADDLOG_INFO(LOG_FEATURE_EVENT, "CMD_AddEventHandler: arg2 = %i.",arg2); + } + ADDLOG_INFO(LOG_FEATURE_EVENT, "CMD_AddEventHandler: arg1 = %i.",reqArg); + } + if(bTwoArgsMode) { + cmdToCall = Tokenizer_GetArgFrom(3); + } else { + cmdToCall = Tokenizer_GetArgFrom(2); } - cmdToCall = Tokenizer_GetArgFrom(2); eventCode = EVENT_ParseEventName(eventName); if(eventCode == CMD_EVENT_NONE) { @@ -318,7 +376,7 @@ static int CMD_AddEventHandler(const void *context, const char *cmd, const char if(reqArgStr) { EventHandlers_AddEventHandler_String(eventCode,EVENT_DEFAULT,reqArgStr,cmdToCall); } else { - EventHandlers_AddEventHandler_Integer(eventCode,EVENT_DEFAULT,reqArg,cmdToCall); + EventHandlers_AddEventHandler_Integer(eventCode,EVENT_DEFAULT,reqArg,arg2,cmdToCall); } return 1; @@ -361,7 +419,7 @@ static int CMD_AddChangeHandler(const void *context, const char *cmd, const char ADDLOG_INFO(LOG_FEATURE_EVENT, "CMD_AddChangeHandler: added %s with cmd %s",eventName,cmdToCall); - EventHandlers_AddEventHandler_Integer(eventCode,relationCode,reqArg,cmdToCall); + EventHandlers_AddEventHandler_Integer(eventCode,relationCode,reqArg,0,cmdToCall); return 1; } diff --git a/src/cmnds/cmd_public.h b/src/cmnds/cmd_public.h index f4f7c104b..1a04c9499 100644 --- a/src/cmnds/cmd_public.h +++ b/src/cmnds/cmd_public.h @@ -54,6 +54,25 @@ enum EventCode { // You can fire an event when TuyaMCU or something receives given string CMD_EVENT_ON_UART, + // IR events + // There will be separate event types for common IR protocol, + // but we will also have a generic IR event with protocol name or index. + // I have decided to have both, because per-protocol events with + // a single integer arguments can be faster and easier to write, + // and we have a whole byte for event index so they don't + // add much overheat. So... + CMD_EVENT_IR_SAMSUNG, // Argument: [Address][Command] + CMD_EVENT_IR_RC5, // Argument: [Address][Command] + CMD_EVENT_IR_RC6, // Argument: [Address][Command] + CMD_EVENT_IR_SONY, // Argument: [Address][Command] + CMD_EVENT_IR_PANASONIC, // Argument: [Address][Command] + CMD_EVENT_IR_SAMSUNG_LG, // Argument: [Address][Command] + CMD_EVENT_IR_SHARP, // Argument: [Address][Command] + CMD_EVENT_IR_NEC, // Argument: [Address][Command] + + //CMD_EVENT_GENERIC, // TODO? + + // must be lower than 256 CMD_EVENT_MAX_TYPES }; @@ -96,6 +115,7 @@ void EventHandlers_FireEvent_String(byte eventCode, const char *argument); // This is useful to fire an event when, for example, a button is pressed. // Then eventCode is a BUTTON_PRESS and argument is a button index. void EventHandlers_FireEvent(byte eventCode, int argument); +void EventHandlers_FireEvent2(byte eventCode, int argument, int argument2); // This is more advanced event handler. It will only fire handlers when a variable state changes from one to another. // For example, you can watch for Voltage from BL0942 to change below 230, and it will fire event only when it becomes below 230. void EventHandlers_ProcessVariableChange_Integer(byte eventCode, int oldValue, int newValue); diff --git a/src/driver/drv_ir.cpp b/src/driver/drv_ir.cpp index 817de5d5c..6be66101e 100644 --- a/src/driver/drv_ir.cpp +++ b/src/driver/drv_ir.cpp @@ -577,60 +577,86 @@ extern "C" void DRV_IR_RunFrame(){ if (ourReceiver){ if (ourReceiver->decode()) { - char out[40]; - PrintIRData(&ourReceiver->decodedIRData); - const char *name = ProtocolNames[ourReceiver->decodedIRData.protocol]; - ADDLOG_INFO(LOG_FEATURE_IR, (char *)"IR decode returned true, protocol %s (%d)", name, (int)ourReceiver->decodedIRData.protocol); + // 'UNKNOWN' protocol is by default disabled in flags + // This is because I am getting a lot of 'UNKNOWN' spam with no IR signals in room + if(ourReceiver->decodedIRData.protocol != UNKNOWN || (ourReceiver->decodedIRData.protocol == UNKNOWN && CFG_HasFlag(OBK_FLAG_IR_ALLOW_UNKNOWN))) { + char out[40]; + PrintIRData(&ourReceiver->decodedIRData); + const char *name = ProtocolNames[ourReceiver->decodedIRData.protocol]; + ADDLOG_INFO(LOG_FEATURE_IR, (char *)"IR decode returned true, protocol %s (%d)", name, (int)ourReceiver->decodedIRData.protocol); - // if user wants us to publish every received IR data, do it now - if(CFG_HasFlag(OBK_FLAG_IR_PUBLISH_RECEIVED)) { - if (ourReceiver->decodedIRData.protocol == UNKNOWN){ - sprintf(out, "%s-%X", name, ourReceiver->decodedIRData.decodedRawData); - } else { - sprintf(out, "%s-%X-%X", name, ourReceiver->decodedIRData.address, ourReceiver->decodedIRData.command); + // if user wants us to publish every received IR data, do it now + if(CFG_HasFlag(OBK_FLAG_IR_PUBLISH_RECEIVED)) { + if (ourReceiver->decodedIRData.protocol == UNKNOWN){ + sprintf(out, "%s-%X", name, ourReceiver->decodedIRData.decodedRawData); + } else { + sprintf(out, "%s-%X-%X", name, ourReceiver->decodedIRData.address, ourReceiver->decodedIRData.command); + } + MQTT_PublishMain_StringString("ir",out, 0); + } + if(ourReceiver->decodedIRData.protocol != UNKNOWN) { + sprintf(out, "%X", ourReceiver->decodedIRData.command); + int tgType = 0; + switch(ourReceiver->decodedIRData.protocol) + { + case NEC: + tgType = CMD_EVENT_IR_NEC; + break; + case SAMSUNG: + tgType = CMD_EVENT_IR_SAMSUNG; + break; + case SHARP: + tgType = CMD_EVENT_IR_SHARP; + break; + case RC5: + tgType = CMD_EVENT_IR_RC5; + break; + case RC6: + tgType = CMD_EVENT_IR_RC6; + break; + case SONY: + tgType = CMD_EVENT_IR_SONY; + break; + } + EventHandlers_FireEvent2(tgType,ourReceiver->decodedIRData.address,ourReceiver->decodedIRData.command); + } + + /* + if (pIRsend){ + pIRsend->write(&ourReceiver->decodedIRData, (int_fast8_t) 2); + + ADDLOG_INFO(LOG_FEATURE_IR, (char *)"IR send timein %d timeout %d", (int)pIRsend->timein, (int)pIRsend->timeout); + } + */ + + // Print a short summary of received data + //IrReceiver.printIRResultShort(&Serial); + //IrReceiver.printIRSendUsage(&Serial); + if (ourReceiver->decodedIRData.protocol == UNKNOWN) { + ADDLOG_INFO(LOG_FEATURE_IR, (char *)"Received noise or an unknown (or not yet enabled) protocol"); + //Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); + // We have an unknown protocol here, print more info + //IrReceiver.printIRResultRawFormatted(&Serial, true); + } else { + ADDLOG_INFO(LOG_FEATURE_IR, (char *)"Received cmd %08X", ourReceiver->decodedIRData.command); + } + //Serial.println(); + + + /* + * Finally, check the received data and perform actions according to the received command + */ + if (ourReceiver->decodedIRData.command == 0x10) { + // do something + } else if (ourReceiver->decodedIRData.command == 0x11) { + // do something else } - MQTT_PublishMain_StringString("ir",out, 0); } - if(1) { - sprintf(out, "%X", ourReceiver->decodedIRData.command); - - } - -/* - if (pIRsend){ - pIRsend->write(&ourReceiver->decodedIRData, (int_fast8_t) 2); - - ADDLOG_INFO(LOG_FEATURE_IR, (char *)"IR send timein %d timeout %d", (int)pIRsend->timein, (int)pIRsend->timeout); - } -*/ - - // Print a short summary of received data - //IrReceiver.printIRResultShort(&Serial); - //IrReceiver.printIRSendUsage(&Serial); - if (ourReceiver->decodedIRData.protocol == UNKNOWN) { - ADDLOG_INFO(LOG_FEATURE_IR, (char *)"Received noise or an unknown (or not yet enabled) protocol"); - //Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); - // We have an unknown protocol here, print more info - //IrReceiver.printIRResultRawFormatted(&Serial, true); - } else { - ADDLOG_INFO(LOG_FEATURE_IR, (char *)"Received cmd %08X", ourReceiver->decodedIRData.command); - } - //Serial.println(); - - /* - * !!!Important!!! Enable receiving of the next value, - * since receiving has stopped after the end of the current received data packet. - */ - ourReceiver->resume(); // Enable receiving of the next value - - /* - * Finally, check the received data and perform actions according to the received command - */ - if (ourReceiver->decodedIRData.command == 0x10) { - // do something - } else if (ourReceiver->decodedIRData.command == 0x11) { - // do something else - } + /* + * !!!Important!!! Enable receiving of the next value, + * since receiving has stopped after the end of the current received data packet. + */ + ourReceiver->resume(); // Enable receiving of the next value } } } diff --git a/src/driver/drv_main.c b/src/driver/drv_main.c index 7c07db572..2d1fecf0b 100644 --- a/src/driver/drv_main.c +++ b/src/driver/drv_main.c @@ -58,7 +58,7 @@ static driver_t g_drivers[] = { { "TESTLED", Test_LED_Driver_Init, Test_LED_Driver_RunFrame, NULL, NULL, NULL, Test_LED_Driver_OnChannelChanged, false }, #if PLATFORM_BEKEN - { "IR", DRV_IR_Init, DRV_IR_RunFrame, NULL, NULL, NULL, NULL, false }, + { "IR", DRV_IR_Init, NULL, NULL, DRV_IR_RunFrame, NULL, NULL, false }, { "DGR", DRV_DGR_Init, NULL, DRV_DGR_RunEverySecond, DRV_DGR_RunQuickTick, DRV_DGR_Shutdown, DRV_DGR_OnChannelChanged, false }, { "DDP", DRV_DDP_Init, NULL, NULL, DRV_DDP_RunFrame, DRV_DDP_Shutdown, NULL, false }, #endif diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index 86024d1ff..a5c38a685 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -1817,7 +1817,7 @@ const char* g_obk_flagNames[] = { "[LED] remember LED driver state (RGBCW, enable, brightness, temperature) after reboot", "[HTTP] Show actual PIN logic level for unconfigured pins", "[IR] Do MQTT publish for incoming IR data", - "error", + "[IR] Allow 'unknown' protocol", "error", "error", "error", diff --git a/src/new_common.c b/src/new_common.c index d65d99b52..58f78748e 100644 --- a/src/new_common.c +++ b/src/new_common.c @@ -24,6 +24,9 @@ int strIsInteger(const char *s) { return 0; if(*s == 0) return 0; + if(s[0]=='0' && s[1] == 'x'){ + return 1; + } while(*s) { if(isdigit((unsigned char)*s)==false) return 0; diff --git a/src/new_pins.h b/src/new_pins.h index a0175db53..25d94109d 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -124,8 +124,9 @@ typedef struct pinsState_s { #define OBK_FLAG_LED_REMEMBERLASTSTATE 12 #define OBK_FLAG_HTTP_PINMONITOR 13 #define OBK_FLAG_IR_PUBLISH_RECEIVED 14 +#define OBK_FLAG_IR_ALLOW_UNKNOWN 15 -#define OBK_TOTAL_FLAGS 15 +#define OBK_TOTAL_FLAGS 16 #define CGF_MQTT_CLIENT_ID_SIZE 64