TheCrypt0 / yi-hack-v4

New Custom Firmware for Xiaomi Cameras based on Hi3518e Chipset. It features RTSP, SSH, FTP and more!
GNU General Public License v3.0
1.55k stars 218 forks source link

Camera doesn't reconnect to MQTT broker if the broker goes offline temporarily #65

Open alexanv1 opened 5 years ago

alexanv1 commented 5 years ago

Whenever, the MQTT broker goes offline temporarily, camera doesn't reconnect to the broker when it comes back online - i.e. motion events are no longer received by the broker.

Solution is to reboot the camera. I run my own broker and restart it relatively recently when changing config, etc so this becomes very tedious with several cameras.

It would be great if camera could reconnect to the broker same as other MQTT clients do.

seydx commented 5 years ago

That would be great!

gooman-uk commented 5 years ago

I've used code like this before to cover this (note, I'm not up to speed with GitHub and have no time to learn, so don't ask me to pull or push something):

    if ((err = mosquitto_loop(mosq, -1, 1)) != MOSQ_ERR_SUCCESS) {
        fprintf(stderr, "Mosq loop error: %u\n", err);
        fflush(stderr);

    if ((err == MOSQ_ERR_CONN_LOST) || (err == MOSQ_ERR_KEEPALIVE) || (err == MOSQ_ERR_NO_CONN)){
        wait_for_network();
        mosquitto_reconnect(mosq);
    }

Together with:

#include <sys/socket.h>
#include <linux/wireless.h>
#include <sys/ioctl.h>

void wait_for_network()
{
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    struct ifreq ifr = {.ifr_name = "wlan0"};

    if (debug)
        fprintf(stderr, "Waiting for network\n");

    while (true) {
        if (ioctl(sockfd, SIOCGIFADDR, &ifr) == 0) {
            ioctl(sockfd, SIOCGIFFLAGS, &ifr);
            if(debug) fprintf(stderr, "Flags: %x\n", ifr.ifr_flags);
            if (ifr.ifr_flags & IFF_RUNNING)
                break;
        }

        sleep(15);
    }

    if (debug)
        fprintf(stderr, "Network connection now up\n");
}
nicolasgomollon commented 5 years ago

Any update on this? I’m running into the same issue with my setup.

lance36 commented 5 years ago

@TheCrypt0 this should be fixable by using mosquitto_loop_start(); which automatically handles reconnection instead of mosquitto_loop();

seydx commented 5 years ago

@TheCrypt0

Can you look into this? Its really annoying to restart the cam every time :( Im using the mqtt function for my Homebridge plugin

TheCrypt0 commented 5 years ago

Thank you guys for the report of the issue I don't use MQTT myself, testing is the only way to find such issues.

I'm currently a little bit busy for my main job, if someone could send a PR and test it on the mqttv4 repo I'll merge it.

manny199 commented 5 years ago

@lance36 where can I insert mosquitto_loop_start(); which automatically handles reconnection instead of mosquitto_loop()? I do not understand how to use your istructions

tinysnake commented 5 years ago

I use motioneye to send mqtt the other day, and I uses mosquitto_pub to send mqtt message. I think the way mosquitto_pub send message is quite a good solution. It disconnect to the server right after the message been sent. If we do that, then we don't have to worry about the stability of long time connection anymore. But there's a downside though, connecting to the broker every single time may be slower, if the connection time is less than 1 second, then I think it's not a problem anymore.