diff --git a/src/driver/drv_doorSensorWithDeepSleep.c b/src/driver/drv_doorSensorWithDeepSleep.c index 9cd405b0f..8f28395b9 100644 --- a/src/driver/drv_doorSensorWithDeepSleep.c +++ b/src/driver/drv_doorSensorWithDeepSleep.c @@ -18,11 +18,11 @@ #include "../hal/hal_adc.h" #include "../ota/ota.h" -static int setting_timeRequiredUntilDeepSleep = 60; -static int g_noChangeTimePassed = 0; -static int g_initialStateSent = 0; -static int g_emergencyTimeWithNoConnection = 0; +static int g_noChangeTimePassed = 0; // time without change. Every event in any of the doorsensor channels resets it. +static int g_emergencyTimeWithNoConnection = 0; // time without connection to MQTT. Extends the interval till Deep Sleep until connection is established or EMERGENCY_TIME_TO_SLEEP_WITHOUT_MQTT +static int g_lastEventState = -1; // last state of doorsensor channel static int setting_automaticWakeUpAfterSleepTime = 0; +static int setting_timeRequiredUntilDeepSleep = 60; #define EMERGENCY_TIME_TO_SLEEP_WITHOUT_MQTT 60 * 5 @@ -32,6 +32,7 @@ int Simulator_GetNoChangeTimePassed() { int Simulator_GetDoorSennsorAutomaticWakeUpAfterSleepTime() { return setting_automaticWakeUpAfterSleepTime; } + // addEventHandler OnClick 8 DSTime +100 commandResult_t DoorDeepSleep_SetTime(const void* context, const char* cmd, const char* args, int cmdFlags) { const char *a; @@ -57,9 +58,9 @@ commandResult_t DoorDeepSleep_SetTime(const void* context, const char* cmd, cons setting_automaticWakeUpAfterSleepTime = Tokenizer_GetArgInteger(1); } - return CMD_RES_OK; } + void DoorDeepSleep_Init() { // 0 seconds since last change g_noChangeTimePassed = 0; @@ -71,9 +72,41 @@ void DoorDeepSleep_Init() { CMD_RegisterCommand("DSTime", DoorDeepSleep_SetTime, NULL); } +void DoorDeepSleep_QueueNewEvents() { + int i, curr_value; + char sChannel[8]; // channel as a string + char sValue[8]; // channel value as a string + + for (i = 0; i < PLATFORM_GPIO_MAX; i++) { + if (g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep || + g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep_NoPup || + g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep_pd) { + + int channel = g_cfg.pins.channels[i]; + sprintf(sChannel, "%i/get", channel); // manually adding the suffix "/get" to the topic + // Explanation: I manually add "/get" suffix to the sChannel, because for some reason, + // when queued messages are published through PublishQueuedItems(), the + // functionality of appendding /get is disabled (in MQTT_PublishTopicToClient()), + // and there is no flag to enforce it. + // There is only a flag (OBK_PUBLISH_FLAG_FORCE_REMOVE_GET) to remove + // suffix, but for some reason there is no flag to add it. + // Would be great if such flag exists, so I can add it when calling + // MQTT_QueuePublish(), so /get is appended when published through + // PublishQueuedItems(). + + curr_value = CHANNEL_Get(channel); + if (curr_value != g_lastEventState) { + g_lastEventState = curr_value; + sprintf(sValue, "%i", curr_value); // get the value of the channel + MQTT_QueuePublish(CFG_GetMQTTClientId(), sChannel, sValue, 0); // queue the publishing + // Current state (or state change) will be queued and published when device establishes + // the connection to WiFi and MQTT Broker (300 seconds by default for that). + } + } + } +} + void DoorDeepSleep_OnEverySecond() { - int i, bValue; - char tmp[8]; #if PLATFORM_BK7231N || PLATFORM_BK7231T if (ota_progress() >= 0) { @@ -83,39 +116,25 @@ void DoorDeepSleep_OnEverySecond() { // update active g_noChangeTimePassed = 0; g_emergencyTimeWithNoConnection = 0; - } else if (Main_HasMQTTConnected() && Main_HasWiFiConnected()) { - if (g_initialStateSent < 3) { - for (i = 0; i < PLATFORM_GPIO_MAX; i++) { - if (g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep || - g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep_NoPup || - g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep_pd) { - sprintf(tmp, "%i", g_cfg.pins.channels[i]); - bValue = BIT_CHECK(g_initialPinStates, i); - MQTT_PublishMain_StringInt(tmp,bValue, 0); - } - } - g_initialStateSent++; - } else { - for (i = 0; i < PLATFORM_GPIO_MAX; i++) { - if (g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep || - g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep_NoPup || - g_cfg.pins.roles[i] == IOR_DoorSensorWithDeepSleep_pd) { - MQTT_ChannelPublish(g_cfg.pins.channels[i], 0); - } + } else if (Main_HasMQTTConnected() && Main_HasWiFiConnected()) { // executes every second when connection is established + + DoorDeepSleep_QueueNewEvents(); + PublishQueuedItems(); // publish those items that were queued when device was offline + + g_noChangeTimePassed++; + if (g_noChangeTimePassed >= setting_timeRequiredUntilDeepSleep) { + // start deep sleep in the next loop + // The deep sleep start will check for role: IOR_DoorSensorWithDeepSleep + // and for those pins, it will wake up on the pin change to opposite state + // (so if door sensor is low, it will wake up on rising edge, + // if door sensor is high, it will wake up on falling) + g_bWantPinDeepSleep = true; + g_pinDeepSleepWakeUp = setting_automaticWakeUpAfterSleepTime; } - } - g_noChangeTimePassed++; - if (g_noChangeTimePassed >= setting_timeRequiredUntilDeepSleep) { - // start deep sleep in the next loop - // The deep sleep start will check for role: IOR_DoorSensorWithDeepSleep - // and for those pins, it will wake up on the pin change to opposite state - // (so if door sensor is low, it will wake up on rising edge, - // if door sensor is high, it will wake up on falling) - g_bWantPinDeepSleep = true; - g_pinDeepSleepWakeUp = setting_automaticWakeUpAfterSleepTime; - } } - else { + else { // executes every second while the device is woken up, but offline + DoorDeepSleep_QueueNewEvents(); + g_emergencyTimeWithNoConnection++; if (g_emergencyTimeWithNoConnection >= EMERGENCY_TIME_TO_SLEEP_WITHOUT_MQTT) { g_bWantPinDeepSleep = true; @@ -124,10 +143,10 @@ void DoorDeepSleep_OnEverySecond() { } } - void DoorDeepSleep_StopDriver() { } + void DoorDeepSleep_AppendInformationToHTTPIndexPage(http_request_t* request) { int untilSleep; @@ -152,9 +171,3 @@ void DoorDeepSleep_OnChannelChanged(int ch, int value) { g_emergencyTimeWithNoConnection = 0; } } - - - - - -