dahua
dahua copied to clipboard
NVR support
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.
I think that's doable. But I don't have an nvr and I'd need one to build out the functionality.
I can help with debugging and testing. Is there a list of API somewhere?
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.
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...
/cgi-bin/magicBox.cgi?action=getDeviceType
type=DHI-NVR2108-8P-4KS2
/cgi-bin/magicBox.cgi?action=getDeviceClass
class=NVR
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
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.
I'll try to prepare PR.
I have a nvr (dahua hcvr5108hs-s3) when I configure the integration it works, but on the integrations page it appears as:
no warning appears in the logs.
I can help, I am fully available
im also using dahua nvr and like to see it supported, when adding the nvr today im getting one camera.
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.
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
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
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.
subtypedenotes main(0)/sub stream(1) Rtsp streams are in the form ofrtsp://<username>:<password>@<ip>:<port>/cam/realmonitor?channel=1&subtype=0Channels 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)
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
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.
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.
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
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.
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
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?
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.
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
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 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, 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.
Awesome, this is totally doable. I'm working on the changes now.
How exciting! looking forward to trying it out 🥳
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
And now 0.9.1 is released for a small bug fix https://github.com/rroller/dahua/releases/tag/0.9.1