shurillu / CTBot

A simple (and easy to use) Arduino Telegram BOT Library for ESP8266/ESP32
MIT License
150 stars 34 forks source link

CTBot stops responding #66

Closed mad-b closed 3 years ago

mad-b commented 3 years ago

Hello. I am using your software to control some I/O's remotely since some time now. I implemented also an external watchdog to prevent freezing even in case of internal watchdogs failures. It resets the reset pin of the esp8266 if not feed. Made power source filters to prevent spikes and noise. Bench tested for weeks.

However: I noted that eventualy the system stops communicating. I think the main software is running normally (I.e. main loop, watchdog feeds etc). However the telegram bot seems dead, and only after reseting the esp8266 it responds again. It only works again if power is cycled.

So my question is. Is there a chance of your lib - or a dependable resource gets stuck/corrupted somehow, so the system keeps running however the program is still running unaware of the lib being 'frozen' ? I mean, main program continues to run, and calling the API etc. However it does not communicate anymore.

Is there a way to, maybe, periodically kill the telegram related objects of your lib then re instantiate it, so circumventing what I think to be a possible memory corruption, or some variable mess up, or even connection state to get unstable, to occur? Or even provoke the external watchdog to trigger.

Can I have a way to instantiate dinamically the bot lib, and check the bot lib sanity, and then take action (delete, allocate the lib again) or so? Or even, a sanity check like "am I online, communicating normally" ?

Can you see if my scenario is possible, then I can add a check and then auto reset the uC ?

-Of course, I will also check if this can be a WiFi connection issue.

Thanks Lissandro

shurillu commented 3 years ago

Hello Lissandro, thank you for using the library. Could I ask what version of the library are you using? Because there is a parallel branch (v3.0.0) rewitten from scratch where several users told me a better stability experience. That new version does not use String objects internally (only for data structure used for exchanging data) and you should only overwrite the old library source code with the new one in that branch and recompile. So if you are not using the new version, would you test it? Take in mind that recently I modify the code preventing some locking scenarios. Some hints:

Let me know if it can solve your issues. If not, we can try to solve together!

Ceers,

Stefano

mad-b commented 3 years ago

Hello Stefano

I will try. It's a bit hard because the equipment is installed remotely. The idea is to control a computer that I access remotely. Previously it stayed on like 24x7, and I used it eventulally so wasting energy. Then I put a relay module and can shutdown the PC via interface, or turn it on (or hard off) via a parallel wire to its power button. But if I need to call someone to reset the bot eventually also, it becames a lot useless most of the time.

Another thing, I noted that the functioning of the bot seems to be "boot-instantiate-use CTBot". If instead I allocate memory for the object, and eventually wants to delete it and reinstantiate, does this would pose some issue or it should work "fresh" each time?

One of my ideas is "if it hanged somehow, delete the object and create it again" - if a reboot is not the way at the moment.

I can go with the reboot option also, but would like to know.

Also, eventually the WiFi connection may become frozen, I noted there is not a "Disconnect" method in your interface. Is it feasible (by you or by other means) ?

Best regards Lissandro

mad-b commented 3 years ago

Complementing, I managed to replace the code with the 3.0 as you suggested, then adjusted the code as per the new status from get message, found that I can use WiFi.disconnect() to do what I intended, now it is under run and test again. Hope it dont misbehaves :)

shurillu commented 3 years ago

Hi Lissandro, regarding the WiFI connection tries, it depends on the WiFi signal/the ESP8266 chip in general: here in my house, sometimes it catch the WiFi signal in one-three tries, sometimes more.

Speaking about using a dynamic allocation of a CTBot object, it is possible, take a look to the following sketch. It is a revised version of the echoBot: it uses a dynamic allocated CTBot object to configure the WiFi etc etc. In the main loop, after ten loops, it deallocate the object and reallocate it. Take in mind that the WiFi network is already configured (and you don't need to do it again) but the telegram token is needed.

Another thing to keep in mind is: with this example it is possible to receive multiple times (two times) the same sent message. The reason is behind the telegram message confirmation system: when you inquire the telegram server for new messages, you send the ID of the last received message. The telegram server send all messages after that ID. So, if you don't confirm (with another getNewMessage()) the received messages, telegram server will send another time the same message. It could happen if you get a new message and after that you deallocate the object.

Cheer,

Stefano

#include "CTBot.h"
CTBot* pBot;

String ssid  = "yourSSID"; 
String pass  = "yourPassword";
String token = "yourToken"; 

int i;

void setup() {
    Serial.begin(115200);
    Serial.println("\n\nStarting TelegramBot...");

    pBot = new CTBot;
    if (NULL == pBot) {
        Serial.println("Unable to allocate memory\n");
        while (1);
    }
    Serial.println("CTbot object allocated\n");

    if (!pBot->wifiConnect(ssid, pass))
        Serial.println("WiFi error");

    if (!pBot->setTelegramToken(token))
        Serial.println("Token error");

    if (pBot->testConnection())
        Serial.println("testConnection OK");
    else
        Serial.println("testConnection NOK");

    i = 0;
}

void loop() {
    // a variable to store telegram message data
    TBMessage msg;

    if (NULL == pBot) {
        pBot = new CTBot;
        if (NULL != pBot) {
            pBot->setTelegramToken(token);
            if (pBot->testConnection())
                Serial.println("testConnection OK");
            else
                Serial.println("testConnection NOK");
        }
    }

    if (pBot != NULL) {
        if (pBot->getNewMessage(msg))
            pBot->sendMessage(msg.sender.id, msg.text);
    }
    i++;
    if (i > 9) {
        delete pBot;
        pBot = NULL;
        Serial.println("object deleted");
        i = 0;
    }
    delay(1000);
}
mad-b commented 3 years ago

Thanks for your tips, before you confirmed I tried this in a similar way. I will close this issue