QuantumEntangledAndy / neolink

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

Feature/optional MQTT discovery #95

Closed kevin-david closed 1 year ago

kevin-david commented 1 year ago

Adds config options to enable MQTT Discovery as documented here: https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery

As discussed in https://github.com/QuantumEntangledAndy/neolink/pull/14#issuecomment-1561076262

Unfortinuately, the floodlight/spotlight doesn't show up in the <AbilityInfo> returned by the camera: https://github.com/QuantumEntangledAndy/neolink/pull/14#issuecomment-1563728970

Open to other suggestions on how to detect or enable these options.

QuantumEntangledAndy commented 1 year ago

We still might be able to detect the abilities. I only decode know xml fields. If the spot light stuff is in a field I haven't added then maybe we just need to add it.

To be sure we need to see the network dumps of the packets just after login from an official client.

kevin-david commented 1 year ago

We still might be able to detect the abilities. I only decode know xml fields. If the spot light stuff is in a field I haven't added then maybe we just need to add it.

To be sure we need to see the network dumps of the packets just after login from an official client.

Here's what I pulled from Wireshark with the filter ip.src == <floodlight_ip> && baichuan && xml

The method I used in https://github.com/thirtythreeforty/neolink/issues/324#issuecomment-1328522026 didn't seem to be working anymore, so I used the previous Mac client found here as you suggested here: https://github.com/thirtythreeforty/neolink/issues/324#issuecomment-1328461894

Large XML dump ```xml 00000000065536 0 0 0 light 1 1 0 1 0000000053056174 English 0 none LIGHT 50331779 0 0 0 0 0 0 NTSC MDY 0 0 1 1 0 Backyard Floodlight 0 mainStream 704 480 0 0 subStream 704 480 0 0 admin system, network, alarm, record, video, image admin general_rw, norm_rw, version_ro, uid_ro, autoReboot_rw, restore_rw, reboot_rw, shutdown_rw, dst_rw, log_ro, output_rw, performance_ro, upgrade_rw, export_rw, import_rw, bootPwd_rw 0 download_rw, fileFind_rw, manualRecord_rw, recordCfg_rw, recordSchedule_rw, subStreamRecord_ro port_rw, dns_rw, email_rw, ipFilter_rw, localLink_rw, pppoe_rw, upnp_rw, ntp_rw, netStatus_rw, ptop_rw hddFull_rw, hddError_rw, disconnect_rw, ipConflict_rw, rfAlarm_rw 0 motion_rw, videoLost_rw, hide_rw 0 ispBasic_rw 1 1 1 1 1 0 1 1 1 1 1 0 admin 1 1 none 0 0 0 1 1 none 0 0 1 7 0 1 1 0 0 1 0 0 0 4 0 1 1 1 3 1 1 0 0 24 21 0 3 0 0 1 1 0 0 1 1 0 2 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 googleHome 1 amazonAlexa 1 0 0 0 0 0 0 0 195 0 0 1 348 791 64 88003 0 0 0 1 7 0 0 0 20 0 0 0 0 1 ```

The only really interesting thing I see there is <typeInfo>LIGHT</typeInfo> - but there are other cameras with spotlights so that doesn't seem like a reliable way to detect... am I missing any messages?

QuantumEntangledAndy commented 1 year ago

The only really interesting thing I see there is LIGHT - but there are other cameras with spotlights so that doesn't seem like a reliable way to detect... am I missing any messages?

Let's try something else. There's an rest api that Reolink uses too

curl -v -X GET 'https://apis.reolink.com/v1.0/devices/YOUR_UID/profile' -H 'Cookie: REO_LANGUAGE=;' 

Put in YOUR_UID and see what the reply is

kevin-david commented 1 year ago

Let's try something else. There's an rest api that Reolink uses too

curl -v -X GET 'https://apis.reolink.com/v1.0/devices/YOUR_UID/profile' -H 'Cookie: REO_LANGUAGE=;' 

Put in YOUR_UID and see what the reply is

Pardon the potentially dumb questions but:

QuantumEntangledAndy commented 1 year ago

The UID of your camera. No authentication. Yes Reolink does it unauthorised. It should display camera model etc. but perhaps in your case it will be contain the light type details too.

QuantumEntangledAndy commented 1 year ago

The UID is usually on the model. But you can usually find it in the official Reolink app too

QuantumEntangledAndy commented 1 year ago

image

kevin-david commented 1 year ago

The UID of your camera. No authentication. Yes Reolink does it unauthorised. It should display camera model etc. but perhaps in your case it will be contain the light type details too.

Got it. Here's the camera with floodlights:

{
    "uid": "<redacted>",
    "model": "Reolink Duo Floodlight PoE",
    "board": "IPC_529B17B8MP",
    "type": "IPC",
    "hwVersion": "B17B5298M_V2",
    "p2p": {
        "enabled": true,
        "activated": true,
        "activatedAt": <redacted>,
        "firstUsedAt": 0
    },
    "hwFeatures": {
        "ethInterface": 2,
        "cellNetwork": 1,
        "reproduced": 0
    },
    "qrScan": {
        "mode": 0,
        "distance": 20,
        "languages": [
            "en-us"
        ],
        "showCountryCode": 1,
        "attributes": 0
    },
    "batteryType": 0,
    "wifiType": 1,
    "maxChannels": 1
}

Without the camera:

{
    "uid": "<redacted>",
    "model": "Reolink Floodlight PoE",
    "board": "F1_5628M",
    "type": "LIGHT",
    "hwVersion": "F15562_V1",
    "p2p": {
        "enabled": true,
        "activated": true,
        "activatedAt": <redacted>,
        "firstUsedAt": 0
    },
    "hwFeatures": {
        "ethInterface": 2,
        "cellNetwork": 1,
        "reproduced": 0
    },
    "qrScan": {
        "mode": 0,
        "distance": 0,
        "languages": [
            "en-us"
        ],
        "showCountryCode": 1,
        "attributes": 0
    },
    "batteryType": 0,
    "wifiType": 1,
    "maxChannels": 1
}

So unfortunately nothing useful there except the device type...

QuantumEntangledAndy commented 1 year ago

Maybe we can use this part

<IOTsupport>
<alertorBell>
<startStop>1</startStop>
<type>1</type>
<duration>1</duration>
<repeatCount>1</repeatCount>
<volume>1</volume>
<audioID>1</audioID>
</alertorBell>
<alertorLight>
<openClose>1</openClose>
<type>1</type>
<flashfreq>1</flashfreq>
<duration>1</duration>
<brightness>1</brightness>
</alertorLight>
</IOTsupport>

I think it is a list of IOT devices for googlehome etc to plugin to.

QuantumEntangledAndy commented 1 year ago

Once I am back home I might play with this and the Siren on the camera. Might also be able to add the Camera discovery too

QuantumEntangledAndy commented 1 year ago

Any ways do you think it is ok to merge? I'm not using HA so I'll have to rely on your tests until I am home and can setup a test environmrnt

QuantumEntangledAndy commented 1 year ago

If you do think it is ready please add something to the README.md to help user know it is there

kevin-david commented 1 year ago

@QuantumEntangledAndy

If you do think it is ready please add something to the README.md to help user know it is there

Done. I think it's good enough to continue to iterate on!

BTW, the next thing I'd like to do is make the floodlight on/off manual time configurable: https://github.com/QuantumEntangledAndy/neolink/pull/14#discussion_r1204052947

I see two approaches:

Any thoughts on which makes more sense? Or another approach you think would work better?

QuantumEntangledAndy commented 1 year ago

Option two over mqtt I think.

QuantumEntangledAndy commented 1 year ago

Since I don't have floodlights to test this I am going to add camera preview discovery too

QuantumEntangledAndy commented 1 year ago

Ok it's pretty cool, the way it works. Try out features = ["camera"] on your config and the latest build. It's just a preview image updated every 0.5s but should still be useful for quick checks and maybe as a thumbnail too

QuantumEntangledAndy commented 1 year ago

Went and added the features ["camera", "motion", "led", "ir", "reboot", "pt"] could you test to make sure nothing broke on your end. Seems to work for me but need to test with a cam that lacks certain things like he floodlight

QuantumEntangledAndy commented 1 year ago

So I learned something new about the protocol today. The camera has it's own set of message numbers and will create new messages nums e.g. when doing snap jpeg images and motion messages

Before I only ever had motion messages being generated by the camera and since it was the only source of new message numbers I could ignore them. Now however I have both motion AND snap making new message numbers so I couldn't ignore them anymore.

This means I had to rewrite the messaging protocol to handle these cases.... Too much work but it is done now... This PR is getting bigger and bigger

QuantumEntangledAndy commented 1 year ago

Please give it another test and if it works for you then we will merge

QuantumEntangledAndy commented 1 year ago

p.s. added battery feature too

Screenshot 2023-06-08 at 16 10 01
QuantumEntangledAndy commented 1 year ago

As one last thing I went and made it possible to disable the threads.

In another PR I'd like to add the ability to manually disconnect/connect camera too so battery can be saved when no one is listen to the data

kevin-david commented 1 year ago

Please give it another test and if it works for you then we will merge

Seems to work, except my camera did stop getting updated images? Not a huge deal for me as I was really only using the floodlight control, but is it still working for you?

There's still a single warning on startup, not sure if it's worth fixing:

[2023-06-09T12:41:59Z DEBUG neolink_core::bc_protocol::connection::bcconn] Ignoring uninteresting message id 78 (number: 0)
[2023-06-09T12:41:59Z DEBUG neolink_core::bc_protocol::connection::bcconn] Ignoring uninteresting message id 79 (number: 0)
[2023-06-09T12:41:59Z DEBUG rumqttc::state] Publish. Topic = neolink/backyard_camera/status/floodlight, Pkid = 9, Payload Size = 3
[2023-06-09T12:41:59Z WARN  neolink_core::bc_protocol::connection::bcconn] Reaching limit of channel
[2023-06-09T12:41:59Z WARN  neolink_core::bc_protocol::connection::bcconn] Remaining: 0 of 100 message space for 5 (ID: 109)
[2023-06-09T12:41:59Z DEBUG rumqttc::state] Publish. Topic = neolink/backyard_floodlight/status/motion, Pkid = 8, Payload Size = 3
[2023-06-09T12:41:59Z DEBUG rumqttc::state] Publish. Topic = neolink/backyard_floodlight/status/floodlight, Pkid = 9, Payload Size = 3
QuantumEntangledAndy commented 1 year ago

This

Remaining: 0 of 100 message space for 5 (ID: 109)

means its reached the max number of messages in the queue for snap shot images. Is this for the floodlight? I would have thought that it would stop before then

kevin-david commented 1 year ago

It's for the other device I have, a PoE camera (which happens to have a spotlight). Double checked by removing the floodlight from the config.

On Fri, Jun 9, 2023 at 9:30 AM Andrew King @.***> wrote:

This

Remaining: 0 of 100 message space for 5 (ID: 109)

means its reached the max number of messages in the queue for snap shot images. Is this for the floodlight? I would have thought that it would stop before then

— Reply to this email directly, view it on GitHub https://github.com/QuantumEntangledAndy/neolink/pull/95#issuecomment-1584580426, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOVQ4T4LJU6A35YGT23C6LXKMQODANCNFSM6AAAAAAYRJJO7M . You are receiving this because you authored the thread.Message ID: @.***>

QuantumEntangledAndy commented 1 year ago

Ok, so for some reason messages are queuing, if you have a wireshark dump I might be able to tell whats up

kevin-david commented 1 year ago

Here's a Wiresharp dump... warning_tcp_errors.pcapng.gz

Removed a few login messages. It looks like there's definitely some TCP-level connection issues, and a lot of traffic over a short time, could be related?

QuantumEntangledAndy commented 1 year ago

Which one is the camera ip, .194 or .150?

QuantumEntangledAndy commented 1 year ago

Guessing .194 from the payloads..

QuantumEntangledAndy commented 1 year ago

This is quite a small sample size there is only 0.71 seconds of buachan data. Not enough to even see one shapshot frame complete

Is there anymore here or does comunication just stop

QuantumEntangledAndy commented 1 year ago

I'd like to get to the bottom of this because this sort of error suggests that there is an async task that is not yielding somewhere

Under normal operations a channel should not fillup, a packet should be placed and then removed from the queue quite quikcly before it has time to fill.

If however there is a thread somewhere that is not yielding control it will cause the items to not be pulled from the queue.

Its difficult to diagnose though as it is an error occuring elsewhere in the code without a good way to tell where

Is there anything about your setup you can tell me that might help to isolate it or even replicate it

kevin-david commented 1 year ago

Guessing .194 from the payloads..

Yep! 192.168.1.150 is the machine I was building/debugging Neolink on, my 2019 Macbook Pro.

This is quite a small sample size there is only 0.71 seconds of buachan data. Not enough to even see one shapshot frame complete

That was intentional - I ran it up to the first warning that Neolink delivered. Figured that would be enough to diagnose the issue without having a bunch of irrelevant noise, but happy to get a longer one if necessary.

Is there anymore here or does comunication just stop

I killed the debugger I was running right after the error. Communication continues to happen.

Is there anything about your setup you can tell me that might help to isolate it or even replicate it

Maybe the camera config will help? Also I'm not sure it's relevant but I was doing this over WiFi. It's fast WiFi that normally works well (I can usually pull 400mbps down) but maybe the slightly larger latency variance is exacerbating the issue. I can test with the container version of this or on a hardwired machine if that makes sense!

[[cameras]]
name = "backyard_camera"
username = "admin"
password = "<admin_pass>"
address = "192.168.1.194:9000"
mqtt.broker_addr = "192.168.1.122"
mqtt.port = 1883
mqtt.credentials = ["homeassistant", "<mqtt_pass>"]
mqtt.discovery.topic = "homeassistant"
mqtt.discovery.features = ["camera", "floodlight", "motion", "pir", "led", "reboot"]
QuantumEntangledAndy commented 1 year ago

A longer dump would be helpful to see if communication resumes. This may just be that the camera is dumping the whole jpeg too fast into our queue. In which case I can safely bump up the queue size. But I want to eliminate other errors before I do that as it can lead to increased memory and hide issues for later.

QuantumEntangledAndy commented 1 year ago

I think I will merge the PR for now and debug this in another issue. Thanks for the work on it. It's quite nice to be able to do home assistant integration like this.

MiAutomations commented 1 year ago

Guessing .194 from the payloads..

Yep! 192.168.1.150 is the machine I was building/debugging Neolink on, my 2019 Macbook Pro.

This is quite a small sample size there is only 0.71 seconds of buachan data. Not enough to even see one shapshot frame complete

That was intentional - I ran it up to the first warning that Neolink delivered. Figured that would be enough to diagnose the issue without having a bunch of irrelevant noise, but happy to get a longer one if necessary.

Is there anymore here or does comunication just stop

I killed the debugger I was running right after the error. Communication continues to happen.

Is there anything about your setup you can tell me that might help to isolate it or even replicate it

Maybe the camera config will help? Also I'm not sure it's relevant but I was doing this over WiFi. It's fast WiFi that normally works well (I can usually pull 400mbps down) but maybe the slightly larger latency variance is exacerbating the issue. I can test with the container version of this or on a hardwired machine if that makes sense!

[[cameras]]
name = "backyard_camera"
username = "admin"
password = "<admin_pass>"
address = "192.168.1.194:9000"
mqtt.broker_addr = "192.168.1.122"
mqtt.port = 1883
mqtt.credentials = ["homeassistant", "<mqtt_pass>"]
mqtt.discovery.topic = "homeassistant"
mqtt.discovery.features = ["camera", "floodlight", "motion", "pir", "led", "reboot"]

Great work thank you !!

MiAutomations commented 1 year ago

I think I will merge the PR for now and debug this in another issue. Thanks for the work on it. It's quite nice to be able to do home assistant integration like this.

Please let me know when this is available, I will try to test with a POE FloodLight that I have

Thank you

MiAutomations commented 1 year ago

Hello

I just need some help in order to try teste this, thank you if you can help me in advance

I just removed a old versions of the neolink that I have working

I removed the directory and I download the new release v0.5.13 I copied to the same original directory

/usr/local/bin/

I created a new config file with the following configurations

´´´ [[cameras]] name = "backyard_camera" Name of the FloodLight username = "admin" Camera User password = "" camera password address = "192.168.1.194:9000" IP address of the camera mqtt.broker_addr = "192.168.1.122" IP address of MY home Assistant
mqtt.port = 1883 mqtt.credentials = ["MymqttUser in Home Assistant", ""] mqtt.discovery.topic = "homeassistant" mqtt.discovery.features = ["camera", "floodlight", "motion", "pir", "led", "reboot"] ´´´ Right now I have this

image

I try to start de neolink with the: neolink --config config.toml but without success

image

Can you please let me know what I'm doing wrong?

Thank you and best regards

QuantumEntangledAndy commented 1 year ago

This is basic PATH stuff. Maybe you should read up on how the PATH on Linux machines work.

In this case your final destination of the binary should be

/usr/local/bin/neolink not /usr/local/bin/neolink_versioninfo/neolink

Also make sure you chmod it correctly.

MiAutomations commented 1 year ago

[[cameras]] name = "backyard_camera" username = "admin" password = "" address = "192.168.1.194:9000" mqtt.broker_addr = "192.168.1.122" mqtt.port = 1883 mqtt.credentials = ["homeassistant", ""] mqtt.discovery.topic = "homeassistant" mqtt.discovery.features = ["camera", "floodlight", "motion", "pir", "led", "reboot"]

Thank you for your support

I changed the folder as you mentioned I execute also the chmod

´´´ sudo chmod +x /usr/local/bin/neolink ´´´

But when I try to run the Neolink with the config file config.toml , I continues facing this issue:

image

Can you please help me ?

Thank you in advance

QuantumEntangledAndy commented 1 year ago

Not /usr/local/bin/neolink/neolink /usr/local/bin/neolink the binary must go in the /usr/local/bin/ folder. The config can go anywhere (typical location is /usr/local/etc/) but up to you. The neolink.d is only needed for developers

MiAutomations commented 1 year ago

Not /usr/local/bin/neolink/neolink /usr/local/bin/neolink the binary must go in the /usr/local/bin/ folder. The config can go anywhere (typical location is /usr/local/etc/) but up to you. The neolink.d is only needed for developers

Thank you for your support, now I'm able to start de Neolink

Right now I'm facing other issue:

image

i have a warning and the neolink is always starting again and I don't have any device on the MQTT

QuantumEntangledAndy commented 1 year ago

Did you start the command as

neolink mqtt --config config.toml

Please read the README

kevin-david commented 1 year ago

@QuantumEntangledAndy not sure if something changed in later commits, but I'm seeing more errors like:

[2023-06-22T00:41:46Z WARN  neolink::mqtt] Error: Failed to set camera status light on

    Caused by:
        0: Failed to recieve reply Timeout
        1: deadline has elapsed. Retrying

For just my camera (with a spotlight) but not my floodlight (without a camera) despite the only thing in the mqtt discovery config being "floodlight"

Will attempt to get a packet capture when I have some time

chris24walsh commented 1 year ago

Siren

Any progress with adding Siren control via MQTT? Anxious to use this alongside the floodlight control to round out security posture.