dahua icon indicating copy to clipboard operation
dahua copied to clipboard

NVR support

Open kukulich opened this issue 4 years ago • 90 comments

Is it possible to support NVR? It would be nice to add one device (NVR) and all info about cameras would be detected automatically.

It should also solve a problem when cameras cannot be added because they are connected via NVR and NVR use specific custom IP addresses for them - and the IP addresses are not usable directly.

kukulich avatar Jun 15 '21 19:06 kukulich

I think that's doable. But I don't have an nvr and I'd need one to build out the functionality.

rroller avatar Jun 15 '21 19:06 rroller

I can help with debugging and testing. Is there a list of API somewhere?

kukulich avatar Jun 15 '21 19:06 kukulich

The problem is that I need an actual NVR so I can do edit-test cycles locally to get all the APIs correct. Without that I have no idea if my code would work or even where to start. I have to play around with the APIs to understand them and for that I need an NVR unit.

rroller avatar Jun 15 '21 20:06 rroller

I have already tested some API:

/cgi-bin/magicBox.cgi?action=getSystemInfo

deviceType=31
processor=ST7108
serialNumber=4F07335PAZEEA9B
updateSerial=NVR2X-4KS3

/cgi-bin/magicBox.cgi?action=getSoftwareVersion

version=4.001.0000005.0,build:2020-11-17

/cgi-bin/magicBox.cgi?action=getMachineName

name=NVR

/cgi-bin/magicBox.cgi?action=getVendor

vendor=Dahua

But I don't know what I should test next... If you can guide me, I may be able to send a PR...

kukulich avatar Jun 15 '21 20:06 kukulich

/cgi-bin/magicBox.cgi?action=getDeviceType

type=DHI-NVR2108-8P-4KS2

/cgi-bin/magicBox.cgi?action=getDeviceClass

class=NVR

kukulich avatar Jun 15 '21 20:06 kukulich

This looks like a way to detect number of channels/cameras:

/cgi-bin/configManager.cgi?action=getConfig&name=VideoColor

table.VideoColor[0][0].Brightness=50
table.VideoColor[0][0].ChromaSuppress=50
table.VideoColor[0][0].Contrast=50
table.VideoColor[0][0].Gamma=50
table.VideoColor[0][0].Hue=50
table.VideoColor[0][0].Saturation=50
table.VideoColor[0][0].Style=Standard
table.VideoColor[0][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[0][1].Brightness=50
table.VideoColor[0][1].ChromaSuppress=50
table.VideoColor[0][1].Contrast=50
table.VideoColor[0][1].Gamma=50
table.VideoColor[0][1].Hue=50
table.VideoColor[0][1].Saturation=50
table.VideoColor[0][1].Style=Standard
table.VideoColor[0][1].TimeSection=0 00:00:00-24:00:00
table.VideoColor[0][2].Brightness=50
table.VideoColor[0][2].ChromaSuppress=50
table.VideoColor[0][2].Contrast=50
table.VideoColor[0][2].Gamma=50
table.VideoColor[0][2].Hue=50
table.VideoColor[0][2].Saturation=50
table.VideoColor[0][2].Style=Standard
table.VideoColor[0][2].TimeSection=0 00:00:00-24:00:00
table.VideoColor[1][0].Brightness=50
table.VideoColor[1][0].ChromaSuppress=50
table.VideoColor[1][0].Contrast=50
table.VideoColor[1][0].Gamma=50
table.VideoColor[1][0].Hue=50
table.VideoColor[1][0].Saturation=50
table.VideoColor[1][0].Style=Standard
table.VideoColor[1][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[1][1].Brightness=50
table.VideoColor[1][1].ChromaSuppress=50
table.VideoColor[1][1].Contrast=50
table.VideoColor[1][1].Gamma=50
table.VideoColor[1][1].Hue=50
table.VideoColor[1][1].Saturation=50
table.VideoColor[1][1].Style=Standard
table.VideoColor[1][1].TimeSection=0 00:00:00-24:00:00
table.VideoColor[1][2].Brightness=50
table.VideoColor[1][2].ChromaSuppress=50
table.VideoColor[1][2].Contrast=50
table.VideoColor[1][2].Gamma=50
table.VideoColor[1][2].Hue=50
table.VideoColor[1][2].Saturation=50
table.VideoColor[1][2].Style=Standard
table.VideoColor[1][2].TimeSection=0 00:00:00-24:00:00
table.VideoColor[2][0].Brightness=50
table.VideoColor[2][0].ChromaSuppress=50
table.VideoColor[2][0].Contrast=50
table.VideoColor[2][0].Gamma=50
table.VideoColor[2][0].Hue=50
table.VideoColor[2][0].Saturation=50
table.VideoColor[2][0].Style=Standard
table.VideoColor[2][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[2][1].Brightness=50
table.VideoColor[2][1].ChromaSuppress=50
table.VideoColor[2][1].Contrast=50
table.VideoColor[2][1].Gamma=50
table.VideoColor[2][1].Hue=50
table.VideoColor[2][1].Saturation=50
table.VideoColor[2][1].Style=Standard
table.VideoColor[2][1].TimeSection=0 00:00:00-24:00:00
table.VideoColor[2][2].Brightness=50
table.VideoColor[2][2].ChromaSuppress=50
table.VideoColor[2][2].Contrast=50
table.VideoColor[2][2].Gamma=50
table.VideoColor[2][2].Hue=50
table.VideoColor[2][2].Saturation=50
table.VideoColor[2][2].Style=Standard
table.VideoColor[2][2].TimeSection=0 00:00:00-24:00:00
table.VideoColor[3][0].Brightness=50
table.VideoColor[3][0].ChromaSuppress=50
table.VideoColor[3][0].Contrast=50
table.VideoColor[3][0].Gamma=50
table.VideoColor[3][0].Hue=50
table.VideoColor[3][0].Saturation=50
table.VideoColor[3][0].Style=Standard
table.VideoColor[3][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[3][1].Brightness=50
table.VideoColor[3][1].ChromaSuppress=50
table.VideoColor[3][1].Contrast=50
table.VideoColor[3][1].Gamma=50
table.VideoColor[3][1].Hue=50
table.VideoColor[3][1].Saturation=50
table.VideoColor[3][1].Style=Standard
table.VideoColor[3][1].TimeSection=0 00:00:00-24:00:00
table.VideoColor[3][2].Brightness=50
table.VideoColor[3][2].ChromaSuppress=50
table.VideoColor[3][2].Contrast=50
table.VideoColor[3][2].Gamma=50
table.VideoColor[3][2].Hue=50
table.VideoColor[3][2].Saturation=50
table.VideoColor[3][2].Style=Standard
table.VideoColor[3][2].TimeSection=0 00:00:00-24:00:00
table.VideoColor[4][0].Brightness=50
table.VideoColor[4][0].ChromaSuppress=50
table.VideoColor[4][0].Contrast=50
table.VideoColor[4][0].Gamma=50
table.VideoColor[4][0].Hue=50
table.VideoColor[4][0].Saturation=50
table.VideoColor[4][0].Style=Standard
table.VideoColor[4][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[4][1].Brightness=50
table.VideoColor[4][1].ChromaSuppress=50
table.VideoColor[4][1].Contrast=50
table.VideoColor[4][1].Gamma=50
table.VideoColor[4][1].Hue=50
table.VideoColor[4][1].Saturation=50
table.VideoColor[4][1].Style=Standard
table.VideoColor[4][1].TimeSection=0 00:00:00-24:00:00
table.VideoColor[4][2].Brightness=50
table.VideoColor[4][2].ChromaSuppress=50
table.VideoColor[4][2].Contrast=50
table.VideoColor[4][2].Gamma=50
table.VideoColor[4][2].Hue=50
table.VideoColor[4][2].Saturation=50
table.VideoColor[4][2].Style=Standard
table.VideoColor[4][2].TimeSection=0 00:00:00-24:00:00
table.VideoColor[5][0].Brightness=50
table.VideoColor[5][0].ChromaSuppress=50
table.VideoColor[5][0].Contrast=50
table.VideoColor[5][0].Gamma=50
table.VideoColor[5][0].Hue=50
table.VideoColor[5][0].Saturation=50
table.VideoColor[5][0].Style=Standard
table.VideoColor[5][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[5][1].Brightness=50
table.VideoColor[5][1].ChromaSuppress=50
table.VideoColor[5][1].Contrast=50
table.VideoColor[5][1].Gamma=50
table.VideoColor[5][1].Hue=50
table.VideoColor[5][1].Saturation=50
table.VideoColor[5][1].Style=Standard
table.VideoColor[5][1].TimeSection=0 00:00:00-24:00:00
table.VideoColor[5][2].Brightness=50
table.VideoColor[5][2].ChromaSuppress=50
table.VideoColor[5][2].Contrast=50
table.VideoColor[5][2].Gamma=50
table.VideoColor[5][2].Hue=50
table.VideoColor[5][2].Saturation=50
table.VideoColor[5][2].Style=Standard
table.VideoColor[5][2].TimeSection=0 00:00:00-24:00:00
table.VideoColor[6][0].Brightness=50
table.VideoColor[6][0].ChromaSuppress=50
table.VideoColor[6][0].Contrast=50
table.VideoColor[6][0].Gamma=50
table.VideoColor[6][0].Hue=50
table.VideoColor[6][0].Saturation=50
table.VideoColor[6][0].Style=Standard
table.VideoColor[6][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[6][1].Brightness=50
table.VideoColor[6][1].ChromaSuppress=50
table.VideoColor[6][1].Contrast=50
table.VideoColor[6][1].Gamma=50
table.VideoColor[6][1].Hue=50
table.VideoColor[6][1].Saturation=50
table.VideoColor[6][1].Style=Standard
table.VideoColor[6][1].TimeSection=0 00:00:00-24:00:00
table.VideoColor[6][2].Brightness=50
table.VideoColor[6][2].ChromaSuppress=50
table.VideoColor[6][2].Contrast=50
table.VideoColor[6][2].Gamma=50
table.VideoColor[6][2].Hue=50
table.VideoColor[6][2].Saturation=50
table.VideoColor[6][2].Style=Standard
table.VideoColor[6][2].TimeSection=0 00:00:00-24:00:00
table.VideoColor[7][0].Brightness=50
table.VideoColor[7][0].Contrast=50
table.VideoColor[7][0].Hue=50
table.VideoColor[7][0].Saturation=50
table.VideoColor[7][0].TimeSection=1 00:00:00-24:00:00
table.VideoColor[7][1].Brightness=50
table.VideoColor[7][1].Contrast=50
table.VideoColor[7][1].Hue=50
table.VideoColor[7][1].Saturation=50
table.VideoColor[7][1].TimeSection=0 00:00:00-24:00:00

kukulich avatar Jun 15 '21 21:06 kukulich

I’m also interested in the NVR integration. I have a Dahua 4108 NVR, installed this great integration and I see “main” camera added and I have a preview of one of the cameras. But only one camera is visible. I simply added the IP of the dahua NVR and it detected 1 Device with 5 entities.

alanpilz avatar Jun 15 '21 22:06 alanpilz

I'll try to prepare PR.

kukulich avatar Jun 16 '21 06:06 kukulich

I have a nvr (dahua hcvr5108hs-s3) when I configure the integration it works, but on the integrations page it appears as:

Captura

no warning appears in the logs.

I can help, I am fully available

frapersan avatar Jun 16 '21 08:06 frapersan

im also using dahua nvr and like to see it supported, when adding the nvr today im getting one camera.

chali272 avatar Jun 16 '21 14:06 chali272

I did not find any API to detect number of cameras... However it may be possible to detect if the device is NVR (via getDeviceClass) so the best option would be to add second config_flow step - user can specify the number of cameras/channels by itself.

kukulich avatar Jun 16 '21 20:06 kukulich

Okay So I was going through the code and in camera.py I saw this

For now we'll only support 1 channel. I don't have any cams where I can test a second channel. I'm not really sure what channel 2 means anyways, it doesn't seem to be the substream. CHANNEL = 1

Channel refers to dvr/xvr/nvr channels. subtype denotes main(0)/sub stream(1) Rtsp streams are in the form of rtsp://<username>:<password>@<ip>:<port>/cam/realmonitor?channel=1&subtype=0

Channels are offset by one. Channel 0 = Camera 1; 1=2; 2=3 etc.

I use this right now and I am able to get all events from an xvr running 11 analog cameras.

https://github.com/algirdasc/appdaemon-apps/blob/master/dahua_mqtt.py

Mikefila avatar Jun 19 '21 02:06 Mikefila

Probably the most important part, the only thing I had to modify was a setting. Instead of defining a camera in the form of camera/1 I removed the number and just used camera

Mikefila avatar Jun 19 '21 02:06 Mikefila

Okay So I was going through the code and in camera.py I saw this

For now we'll only support 1 channel. I don't have any cams where I can test a second channel. I'm not really sure what channel 2 means anyways, it doesn't seem to be the substream. CHANNEL = 1

Channel refers to dvr/xvr/nvr channels. subtype denotes main(0)/sub stream(1) Rtsp streams are in the form of rtsp://<username>:<password>@<ip>:<port>/cam/realmonitor?channel=1&subtype=0

Channels are offset by one. Channel 0 = Camera 1; 1=2; 2=3 etc.

I use this right now and I am able to get all events from an xvr running 11 analog cameras.

https://github.com/algirdasc/appdaemon-apps/blob/master/dahua_mqtt.py

noob questone, what file is this replacing in the Dahua folder/whats should your file be named as? (i cant see any file named dahua_mqtt.py)

chali272 avatar Jun 19 '21 12:06 chali272

I'm sorry if I was unclear, I did not change anything on this integration nor do I have it working.

The link I posted is a different integration all together. It works through appdaemon. I only referenced so the maintainer of this integration has a working example of a script that will log on to a nvr/dvr/xvr. Perhaps it maybe helpful.

Follow this post for details of the other integration, if you have further questions please post them to that thread. I'm subscribed and will answer there as not to derail this thread.

https://community.home-assistant.io/t/dahua-ipc-to-mqtt-app/93327/174?u=mikefila

Mikefila avatar Jun 19 '21 17:06 Mikefila

what is this section undr init.py? def init(self, hass: HomeAssistant, events: list, address: str, port: int, rtsp_port: int, username: str, password: str) -> None: """Initialize.""" self.client: DahuaClient = DahuaClient(username, password, address, port, rtsp_port, async_get_clientsession(hass)) self.dahua_event: DahuaEventThread self.platforms = [] self.initialized = False self.model = "" self.machine_name = "" self.connected = None self.channels = {"1": "1"} self.events: list = events

If we use NVR address, it works and events are registered, but only for channel 1. Also there is no way to modify entity name, so even if we modify the channel in the code, it will link it to the same one.

fokcuk avatar Jun 27 '21 13:06 fokcuk

Yeah I have a hard coded channel coded through the code. I can make that an option when configuring the integration to allow you to pick the channel. I think that will work.

rroller avatar Jun 27 '21 14:06 rroller

Yeah I have a hard coded channel coded through the code. I can make that an option when configuring the integration to allow you to pick the channel. I think that will work.

And make am option for entity name pick, otherwise it assigns the same name to the same NVR when adding and no option to change it. Which file picks the channel for events? I saw in one there is 1:1 for a channel, but don't know it its a start:end (like 1:5) or if you want a particular channel you have to select 2:2, 3:3 etc

fokcuk avatar Jun 27 '21 23:06 fokcuk

I'm close to completing a change that allows one to set the name during configuration time. This will be the building blocks needed to support channels.

It's basically the same configuration form now, but after you click submit, it'll open a new form with the name of the camera and lets you edit it.

rroller avatar Jun 29 '21 04:06 rroller

great! thank you. How does it get the motion events? I thought I changed the channel info in the code but I think it reads any motion event and NVR will have different events for different channels/cameras

fokcuk avatar Jun 29 '21 05:06 fokcuk

Platform dahua does not generate unique IDs. ID 3CPAZ5EF403317U_motion_detection already exists - ignoring switch.nvr_motion_detection Platform dahua does not generate unique IDs. ID 3CPAZ5EF403317U_disarming already exists - ignoring switch.nvr_disarming

Can you please add the sensor unique IDs as well?

fokcuk avatar Jun 29 '21 14:06 fokcuk

I'm close to completing a change that allows one to set the name during configuration time. This will be the building blocks needed to support channels.

It's basically the same configuration form now, but after you click submit, it'll open a new form with the name of the camera and lets you edit it.

@rroller Ill be eager to test this when you have finished.

haid45 avatar Jul 06 '21 04:07 haid45

Thanks. I'll make this the next thing I work on. I need to un-hard-code all the channels I currently have hard coded

rroller avatar Jul 06 '21 04:07 rroller

Amazing, I'm readily available to test this out for you. I currently have an NVR installed with 4 cameras (channels). The integration is able to pick up just the main channel at the moment.

haid45 avatar Jul 06 '21 04:07 haid45

@haid45 when you added your camera, for the IP address, do you use your NVR IP Address? I assume you don't use the IP of the camera? So you'd be adding 4 camera's all with the IP of your NVR?

rroller avatar Jul 06 '21 04:07 rroller

@rroller, yes I used the IP address of the NVR as I wasn't able to get the individual ip's of the cameras. Well actually, I was but they seemed to be on a local network within the NVR because the ip's where along the lines of 10.0.0.1. Adding the 4 cameras with IP of the NVR is definitely the end game here.

haid45 avatar Jul 06 '21 04:07 haid45

Awesome, this is totally doable. I'm working on the changes now.

rroller avatar Jul 06 '21 04:07 rroller

How exciting! looking forward to trying it out 🥳

haid45 avatar Jul 06 '21 05:07 haid45

I just released 0.9.0 with early support for NVR's. I don't have an NVR so I can't test it... so this will most definitely have bugs :)

If you all could please test it and let me know if you run into any issues and I'll try to fix them ASAP.

https://github.com/rroller/dahua/releases/tag/0.9.0

rroller avatar Jul 07 '21 05:07 rroller

And now 0.9.1 is released for a small bug fix https://github.com/rroller/dahua/releases/tag/0.9.1

rroller avatar Jul 07 '21 05:07 rroller