QuantumEntangledAndy / neolink

An RTSP bridge to Reolink IP cameras
GNU Affero General Public License v3.0
250 stars 41 forks source link

Camera stays connected #163

Closed Adammantium closed 9 months ago

Adammantium commented 9 months ago

Describe the bug Hello there, im currently using the latest build of feature/push_mqtt. My cameras still stay connected, am I missing something? I know its experimental, but i was hoping i would be able to test it.

To Reproduce Steps to reproduce the behavior. Example:

  1. Create this configuration file:
    [[cameras]]
    name = "reolink1"
    username = "admin"
    password = "***"
    uid = "***"
    stream = "Main"
    idle_disconnect = true
    [cameras.mqtt]
    enable_motion = true
    enable_preview = true
    battery_update = 60000
    preview_update = 2000

    I also tried adding the pause function, had no effect.

    [cameras.pause]
    on_motion = true
    on_client = true
    timeout = 2.1
  2. Launch Neolink: neolink mqtt --config ...
  3. Check MQTT, the camera stays connected

Expected behavior I would expect MQTT to disconnect the cameras as long as there is no motion detected. I don't want the preview to update all the time, only when a motion is detected (+ maybe every few minutes) so i can grab that picture. Maybe i just didn't understand the configuration properly. preview_update is only the refresh interval inside of MQTT, right? Its not trying to take a picture every 2 seconds, my "framerate" seems to be 1 picture every 10 seconds.

Versions NVR software: Neolink software: 8bdb8ef1bd33bd14acc9555c15154295bdc075a2 (CI #941) Reolink camera model and firmware: Reolink Argus Eco (v3.0.0.1981_23040606) OS: Linux Debian 12

Any help would be appreciated! Thank you.

QuantumEntangledAndy commented 9 months ago

So from what I can see from your config it seems fine. You can set the preview to anything you want it will ignore it when it goes to idle disconnect and only take a preview when connected.

Perhaps you can set the environmental variable RUST_LOG to "neolink=debug" and post the debug log here. That will tell us what's happening

QuantumEntangledAndy commented 9 months ago

Also is that your exact config copy pasted? It will silently ignore some issue like spelling mistakes so please copy paste it in.

Also for example this would not work

[[cameras]]
name = "reolink1"
username = "admin"
password = "***"
uid = "***"
stream = "Main"
[cameras.mqtt]
enable_motion = true
enable_preview = true
battery_update = 60000
preview_update = 2000
idle_disconnect = true

Because idle_disconnect is not a member of the cameras.mqtt sub table.

QuantumEntangledAndy commented 9 months ago

Here's the config I use for my tests

[[cameras]]
  name = "Cammy01"
  username = "****"
  password = "****"
  address = "****:9000"
  uid = "****"
  stream = "both"
  idle = true

idle is an undocumented alias for idle_disconnect. (I like to keep the keywords in my config short for easy typing, but the official names are long to better describe what they do)

Adammantium commented 9 months ago

Also is that your exact config copy pasted? It will silently ignore some issue like spelling mistakes so please copy paste it in.

Also for example this would not work

[[cameras]]
name = "reolink1"
username = "admin"
password = "***"
uid = "***"
stream = "Main"
[cameras.mqtt]
enable_motion = true
enable_preview = true
battery_update = 60000
preview_update = 2000
idle_disconnect = true

Because idle_disconnect is not a member of the cameras.mqtt sub table.

Oh sorry, you are right, i did some testing at put it in cameras.mqtt for one camera and in the main part for the other one to test it. This is my whole config file:

bind = "0.0.0.0"

[mqtt]
broker_addr = "127.0.0.1" # Address of the mqtt server
port = 1883 # mqtt servers port
credentials = ["***", "***"] # mqtt server login details

[[cameras]]
name = "reolink1"
username = "admin"
password = "***"
uid = "***"
stream = "Main"
idle_disconnect = true
[cameras.pause]
on_motion = true
on_client = true
timeout = 2.1
[cameras.mqtt]
enable_pings = false
enable_motion = true
enable_preview = true
battery_update = 60000
preview_update = 2000

[[cameras]]
name = "reolink2"
username = "admin"
password = "***"
uid = "***"
stream = "Main"
idle_disconnect = true
[cameras.mqtt]
enable_pings = false
enable_motion = true
enable_preview = true
battery_update = 60000
preview_update = 2000

[cameras.mqtt.discovery]
topic = "homeassistant"
features = ["camera", "ir", "motion", "battery"]
Adammantium commented 9 months ago

I also just send you my log file via mail, it looks like its holding a lot of private information. Do you need the file /root/.config/./neolink_token.toml as well? Seems like there is only one key in there:

fcm_token = "***"

[gcm]
android_id = "***"
security_token = "***"

[keys]
public_key = "***"
private_key = "***"
auth_secret = "***"

Maybe its an issue because im using 2 cameras? Edit: Tested it with one, still the same issue

Adammantium commented 9 months ago

I might have figured out the issue, because of the whole retries i tried allowing the cameras back on the internet again. I was blocking their internet access because i dint want the stream online, only in home assistant, but it seems like to be using that feature they need to communicate with reolink servers. Do you know if it would be possible to use it offline?

QuantumEntangledAndy commented 9 months ago

They don't need to communicate with Reolink but they do need to communicate with Google fire cloud messaging for the push notifications. If they don't then we cannot know when the camera gets motion. Since we are disconnected we need a push notification to know when there is any motion

Although depending on how they programmed the push notifications it means they might need to contact Reolink to relay the push notifications to Google

QuantumEntangledAndy commented 9 months ago

Might be possible to do it via a local mail server instead of push notifications but I haven't programmed that in

QuantumEntangledAndy commented 9 months ago

You can set push_notifications = false to disable that and then instead wake the camera yourself manually using with an mqtt command or by starting a stream. In this situation though do no use motion pause

Adammantium commented 9 months ago

I will do some more testing later and share my results. Thank you for the help!

Adammantium commented 9 months ago

One last question for now: Do i need to enable push notifications on my phone as well? It seems to be only working once i enable it on my phone. Will it still work if the phone is offline?

Adammantium commented 9 months ago

I did some more digging, seems like the camera is connecting to 2 servers: pushx.reolink.com and p2p.reolink.com My guess is that pushx is probably handling all the push notifications. So maybe in the future it would be possible to grab that stuff directly to make it work offline. Just by using pihole and redirecting that address to the neolink service.

But for now everything seems to be working fine. Im going to try blocking the p2p domain to at least get something blocked from calling home.

For now this issue is solved :) Thank you.

QuantumEntangledAndy commented 9 months ago

One last question for now: Do i need to enable push notifications on my phone as well? It seems to be only working once i enable it on my phone. Will it still work if the phone is offline?

Should be completly independant. I have push notifications always disabled on my iphone. I don't even have an andriod with reolink to activate it on. We set up a fake andriod ID and push message client on neolink

QuantumEntangledAndy commented 9 months ago

Reolink uses the following domains for it's ip registeration and for relaying video thorugh

"p2p.reolink.com",
"p2p1.reolink.com",
"p2p2.reolink.com",
"p2p3.reolink.com",
"p2p4.reolink.com",
"p2p5.reolink.com",
"p2p6.reolink.com",
"p2p7.reolink.com",
"p2p8.reolink.com",
"p2p9.reolink.com",
"p2p10.reolink.com",
"p2p11.reolink.com",
// These following are all currently set to 127.0.0.1
// probably reserved for future use
// "p2p12.reolink.com",
// "p2p13.reolink.com",
// "p2p14.reolink.com",
// "p2p15.reolink.com",
// "p2p16.reolink.com",

You should set discovery = "local" in neolink config to force it to not contact reolink for discovery of the IP

Adammantium commented 9 months ago

You should set discovery = "local" in neolink config to force it to not contact reolink for discovery of the IP

Is it in the main part of the camera config?

I will see what happens if i blacklist those domains. I just want to try my best and limit the possibility of someone getting in those cameras.

QuantumEntangledAndy commented 9 months ago

No its set individually for each camera please read the discovery section of the readme

QuantumEntangledAndy commented 9 months ago

You may stuggle to connect via a UID if you do not allow broadcasts on your network and you only supply a UID.

You may want to supply the uid and the addr in your config

Adammantium commented 9 months ago

No its set individually for each camera please read the discovery section of the readme

Oh, sorry, i missed that.

You may stuggle to connect via a UID if you do not allow broadcasts on your network and you only supply a UID.

You may want to supply the uid and the addr in your config

Yeah, i will add the IP as well, its a static IP so that wont cause any issues. How would neolink behave if i specify a IP and UID and those two don't match?

QuantumEntangledAndy commented 9 months ago

Yeah, i will add the IP as well, its a static IP so that wont cause any issues. How would neolink behave if i specify a IP and UID and those two don't match?

To initiate a UDP connection we have to send the UID to the camera. Basically the hello message includes the UID and the camera won't reply unless you get it right

Adammantium commented 9 months ago

So if I specify the IP and the camera somehow would get a different IP, it would not be able to connect, right? Or would neolink ignore the IP at some point and make a broadcast?

QuantumEntangledAndy commented 9 months ago

It tries both. It makes a broadcast over the network and at the same time sends the hello message to the ip specifies and which every replies first it uses

Adammantium commented 9 months ago

Okay, thank you for the quick response, everything seems to be working now :)