diff --git a/custom_components/hikvision_next/const.py b/custom_components/hikvision_next/const.py index af4a3f8..cb4dca9 100644 --- a/custom_components/hikvision_next/const.py +++ b/custom_components/hikvision_next/const.py @@ -22,6 +22,7 @@ EVENT_BASIC: Final = "basic" EVENT_IO: Final = "io" EVENT_SMART: Final = "smart" +EVENT_PIR: Final = "pir" EVENTS = { "motiondetection": { "type": EVENT_BASIC, @@ -83,6 +84,13 @@ "proxied_node": "IOProxyInputPort", "device_class": BinarySensorDeviceClass.MOTION, }, + "pir": { + "type": EVENT_PIR, + "label": "PIR", + "slug": "WLAlarm/PIR", + "direct_node": "PIRAlarm", + "device_class": BinarySensorDeviceClass.MOTION, + } } EVENTS_ALTERNATE_ID = { diff --git a/custom_components/hikvision_next/isapi.py b/custom_components/hikvision_next/isapi.py index be0b52d..244900f 100644 --- a/custom_components/hikvision_next/isapi.py +++ b/custom_components/hikvision_next/isapi.py @@ -28,6 +28,7 @@ DOMAIN, EVENT_BASIC, EVENT_IO, + EVENT_PIR, EVENTS, EVENTS_ALTERNATE_ID, MUTEX_ALTERNATE_IDS, @@ -462,6 +463,9 @@ def get_event_url(self, event: SupportedEventsInfo, connection_type: str) -> str else: # ISAPI/System/IO/{slug}}/{channel_id} url = f"System/IO/{slug}/{event.io_port_id}" + elif event_type == EVENT_PIR: + # ISAPI/WLAlarm/PIR + url = slug else: # ISAPI/Smart/{event}/{channel_id} url = f"Smart/{slug}/{event.channel_id}" diff --git a/tests/fixtures/ISAPI/EventNotificationAlert/pir.xml b/tests/fixtures/ISAPI/EventNotificationAlert/pir.xml new file mode 100644 index 0000000..c579c9c --- /dev/null +++ b/tests/fixtures/ISAPI/EventNotificationAlert/pir.xml @@ -0,0 +1,19 @@ + + + 1.0.0.255 + HTTP + c6:e6:61:0a:46:37 + 1 + 2023-04-06T22:22:21+01:00 + 4268 + PIR + active + PIR alarm + Bedroom + + DS-2CD2443G0-IW00000000AAWRE00000000 + PIR&&DS-2CD2443G0-IW00000000AAWRE00000000,2023-04-06T22:22:21+01:00,1,1.0 + + \ No newline at end of file diff --git a/tests/fixtures/devices/DS-2CD2443G0-IW.json b/tests/fixtures/devices/DS-2CD2443G0-IW.json new file mode 100644 index 0000000..42e3f0d --- /dev/null +++ b/tests/fixtures/devices/DS-2CD2443G0-IW.json @@ -0,0 +1,1075 @@ +{ + "data": { + "ISAPI": { + "System/deviceInfo": { + "response": { + "DeviceInfo": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "deviceName": "Pietro", + "deviceID": "a6b9c000-7fc0-00b0-000e-00f0fba00000", + "deviceDescription": "IPCamera", + "deviceLocation": "hangzhou", + "systemContact": "Hikvision.China", + "model": "DS-2CD2443G0-IW", + "serialNumber": "DS-2CD2443G0-IW00000000AAWRE00000000", + "macAddress": "c6:e6:61:0a:46:37", + "firmwareVersion": "V5.6.5", + "firmwareReleasedDate": "build 200316", + "encoderVersion": "V7.3", + "encoderReleasedDate": "build 190910", + "bootVersion": "V1.3.4", + "bootReleasedDate": "100316", + "hardwareVersion": "0x0", + "deviceType": "IPCamera", + "telecontrolID": "88", + "supportBeep": "true", + "supportVideoLoss": "false", + "firmwareVersionInfo": "B-R-G1-0" + } + } + }, + "System/capabilities": { + "response": { + "DeviceCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "SysCap": { + "isSupportDst": "true", + "NetworkCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "isSupportWireless": "true", + "isSupportPPPoE": "true", + "isSupportBond": "false", + "isSupport802_1x": "false", + "isSupportNtp": "true", + "isSupportFtp": "true", + "isSupportUpnp": "true", + "isSupportDdns": "true", + "isSupportHttps": "true", + "SnmpCap": { + "isSupport": "true" + }, + "isSupportExtNetCfg": "false", + "isSupportIPFilter": "true", + "isSupportEZVIZ": "true", + "isSupportEhome": "true", + "isSupportWirelessDial": "false", + "isSupportWirelessServer": "false", + "isSupportWPS": "true", + "isWirelessMutexWithWirelessServer": "true", + "isSupportMACFilter": "false", + "isSupportRFIDData": "false", + "isSupportwifiProbeSSID": "false", + "isSupportWifiProbe": "false", + "isSupportIntegrate": "true", + "isSupportPlatformAccess": "true", + "isSupportGetLinkSocketIP": "true", + "isSupportWebSocket": "true", + "isSupportWebSocketS": "true", + "isSupportVideoImgDB": "false", + "isSupportDynamicHostName": "true" + }, + "IOCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "IOInputPortNums": "0", + "IOOutputPortNums": "0", + "isSupportStrobeLamp": "false" + }, + "SerialCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "rs485PortNums": "0", + "supportRS232Config": "true", + "rs422PortNums": "0", + "rs232PortNums": "1" + }, + "VideoCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "videoInputPortNums": "0", + "videoOutputPortNums": "0", + "isSupportHeatmap": "false", + "isSupportCounting": "false", + "isSupportPicture": "false", + "OSDLanguage": { + "@opt": "GBK,EUC-KR", + "@def": "GBK" + } + }, + "AudioCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "audioInputNums": "1", + "audioOutputNums": "1" + }, + "isSupportExternalDevice": "false", + "isSupportChangedUpload": "true", + "isSupportGettingWorkingStatus": "true", + "isSupportSubscribeEvent": "true", + "isSupportDiagnosedData": "true", + "isSupportMetadata": "true", + "isSupportTimeCap": "true" + }, + "voicetalkNums": "1", + "isSupportSnapshot": "true", + "SecurityCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "supportUserNums": "32", + "userBondIpNums": "0", + "userBondMacNums": "0", + "isSupCertificate": "true", + "issupIllegalLoginLock": "true", + "isSupportOnlineUser": "true", + "isSupportAnonymous": "false", + "isSupportStreamEncryption": "false", + "securityVersion": { + "@opt": "1" + }, + "keyIterateNum": "100", + "isSupportUserCheck": "true", + "isSupportSecurityQuestionConfig": "false", + "supportSecurityNode": { + "@opt": "wirelessServer,wirelessDial" + }, + "SecurityLimits": { + "LoginPasswordLenLimit": { + "@min": "1", + "@max": "16" + }, + "SecurityAnswerLenLimit": { + "@min": "1", + "@max": "128" + } + }, + "RSAKeyLength": { + "@opt": "1024,2048", + "@def": "1024" + }, + "isSupportONVIFUserManagement": "true", + "WebCertificateCap": { + "CertificateType": { + "@opt": "digest,digest/basic" + } + }, + "isSupportConfigFileImport": "true", + "isSupportConfigFileExport": "true", + "cfgFileSecretKeyLenLimit": { + "@min": "1", + "@max": "16" + }, + "isIrreversible": "true", + "salt": "62ed0f42b7250511f0491f335302cea138a73b9692f896001af637512c22013d", + "isSupportOnvifInfo": "true", + "isSupportDeviceSelfSignCertExport": "true" + }, + "EventCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "isSupportHDFull": "true", + "isSupportHDError": "true", + "isSupportNicBroken": "true", + "isSupportIpConflict": "true", + "isSupportIllAccess": "true", + "isSupportViException": "false", + "isSupportViMismatch": "false", + "isSupportRecordException": "false", + "isSupportTriggerFocus": "false", + "isSupportMotionDetection": "true", + "isSupportVideoLoss": "false", + "isSupportTamperDetection": "true", + "isSupportPersonQueueDetection": "false", + "isSupportTeacherBehaviorDetect": "false", + "isSupportFaceSnap": "false", + "isSupportCityManagement": "false", + "isSupportMixedTargetDetection": "false" + }, + "RacmCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "nasNums": "8", + "pictureSearchType": { + "@opt": "CMR,MOTION,pir,LineDetection,FieldDetection" + }, + "recordSearchType": { + "@opt": "CMR,MOTION,EDR,pir,AllEvent,LineDetection,FieldDetection" + } + }, + "SmartCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "isSupportROI": "false", + "isSupportFaceDetect": "false", + "isSupportIntelliTrace": "false", + "isSupportFieldDetection": "true", + "isSupportDefocusDetection": "false", + "isSupportAudioDetection": "false", + "isSupportSceneChangeDetection": "false", + "isSupportLineDetection": "true", + "isSupportRegionEntrance": "false", + "isSupportRegionExiting": "false", + "isSupportLoitering": "false", + "isSupportGroup": "false", + "isSupportRapidMove": "false", + "isSupportParking": "false", + "isSupportUnattendedBaggage": "false", + "isSupportAttendedBaggage": "false", + "isSupportPeopleDetection": "false", + "isSupportSmartCalibration": "true", + "isSupportStorageDetection": "false" + }, + "WLAlarmCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "isSupportTeleControl": "false", + "isSupportPIR": "true", + "isSupportWLSensors": "false", + "isSupportCallHelp": "false", + "WLSensorsNum": "8" + }, + "isSupportGIS": "false", + "isSupportCompass": "false", + "isSupportRoadInfoOverlays": "false", + "TestCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "isSupportFTPTest": "true", + "isSupportPingTest": "true", + "isSupportNTPTest": "true", + "isSupportNASTest": "true", + "isSupportEmailTest": "true" + }, + "PanoramaCap": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "isSupportGeneratePanorama": "false", + "isSupportPanoramaPosition3D": "false", + "isSupportPreset": "false" + }, + "isSupportFaceCaptureStatistics": "false", + "isSupportElectronicsEnlarge": "true", + "isSupportRemoveStorage": "false", + "isSupportFirmwareVersionInfo": "true", + "isSupportLaserSpotManual": "false", + "isSupportRTMP": "false", + "isSupportTraffic": "false", + "isSupportChannelEventListCap": ["true", "true"], + "isSupportCityManagement": "false", + "SDCardCtrlCap": { + "isSupportIOCtrl": "true", + "isSupportReadCardStatus": "true", + "isSupportStartUpdate": "true", + "isSupportEndUpdate": "true", + "isSupportPowerCtrl": "true" + }, + "isSupportActiveMulticast": "true", + "isSupportChannelEventCap": "true", + "isSupportChannelFullEventCap": "true", + "isSupportAUXInfoCap": "true" + } + } + }, + "System/IO/inputs/1/status": { + "status_code": 403 + }, + "System/IO/outputs/1/status": { + "status_code": 403 + }, + "System/Holidays": { + "status_code": 403 + }, + "System/Video/inputs/channels": { + "response": { + "VideoInputChannelList": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "VideoInputChannel": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "1", + "inputPort": "1", + "name": "Camera 01", + "videoFormat": "PAL" + } + } + } + }, + "ContentMgmt/InputProxy/channels": { + "status_code": 403 + }, + "ContentMgmt/Storage": { + "response": { + "storage": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "hddList": { + "@version": "1.0", + "@xmlns": "http://www.hikvision.com/ver10/XMLSchema" + }, + "nasList": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "nas": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "9", + "addressingFormatType": "ipaddress", + "ipAddress": "1.0.0.182", + "portNo": "0", + "nasType": "NFS", + "path": "\\kamera3", + "status": "ok", + "capacity": "15359", + "freeSpace": "512", + "property": "RW", + "mountType": "SMB/CIFS", + "userName": "kamera" + }, + "supportMountType": { + "@opt": "NFS,SMB/CIFS" + }, + "authentication": { + "@opt": "SMB/CIFS" + } + }, + "workMode": "quota" + } + } + }, + "Security/adminAccesses": { + "response": { + "AdminAccessProtocolList": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "AdminAccessProtocol": [ + { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "1", + "enabled": "true", + "protocol": "HTTP", + "portNo": "80" + }, + { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "2", + "enabled": "true", + "redirectToHttps": "false", + "protocol": "HTTPS", + "portNo": "443", + "TLS1_1Enable": "true", + "TLS1_2Enable": "true" + }, + { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "3", + "enabled": "true", + "protocol": "DEV_MANAGE", + "portNo": "8000" + }, + { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "4", + "enabled": "true", + "protocol": "RTSP", + "portNo": "554" + }, + { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "5", + "enabled": "true", + "protocol": "SDK_OVER_TLS", + "portNo": "8443" + }, + { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "6", + "enabled": "true", + "protocol": "WebSocket", + "portNo": "7681" + }, + { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "7", + "enabled": "false", + "protocol": "WebSocketS", + "portNo": "7682" + } + ] + } + } + }, + "Event/triggers": { + "response": { + "EventTriggerList": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "EventTrigger": [ + { + "id": "VMD-1", + "eventType": "VMD", + "eventDescription": "VMD Event trigger Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": [ + { + "id": "record-1", + "notificationMethod": "record", + "videoInputID": "1", + "notificationRecurrence": "beginning" + }, + { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + ] + } + }, + { + "id": "tamper-1", + "eventType": "tamperdetection", + "eventDescription": "shelteralarm Event trigger Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + } + }, + { + "id": "diskfull", + "eventType": "diskfull", + "eventDescription": "exception Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": [ + { + "id": "email", + "notificationMethod": "email", + "notificationRecurrence": "beginning" + }, + { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + ] + } + }, + { + "id": "diskerror", + "eventType": "diskerror", + "eventDescription": "exception Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": [ + { + "id": "email", + "notificationMethod": "email", + "notificationRecurrence": "beginning" + }, + { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + ] + } + }, + { + "id": "nicbroken", + "eventType": "nicbroken", + "eventDescription": "exception Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": null + }, + { + "id": "ipconflict", + "eventType": "ipconflict", + "eventDescription": "exception Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": null + }, + { + "id": "illaccess", + "eventType": "illaccess", + "eventDescription": "exception Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": [ + { + "id": "email", + "notificationMethod": "email", + "notificationRecurrence": "beginning" + }, + { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + ] + } + }, + { + "id": "linedetection-1", + "eventType": "linedetection", + "eventDescription": "Linedetection Event trigger Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + } + }, + { + "id": "fielddetection-1", + "eventType": "fielddetection", + "eventDescription": "fielddetection Event trigger Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + } + }, + { + "id": "videomismatch", + "eventType": "videomismatch", + "eventDescription": "exception Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": { + "id": "beep", + "notificationMethod": "beep", + "notificationRecurrence": "beginning" + } + } + }, + { + "id": "badvideo", + "eventType": "badvideo", + "eventDescription": "exception Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": null + }, + { + "id": "PIR", + "eventType": "PIR", + "eventDescription": "PIR Event trigger Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": { + "EventTriggerNotification": [ + { + "id": "record-1", + "notificationMethod": "record", + "videoInputID": "1", + "notificationRecurrence": "beginning" + }, + { + "id": "center", + "notificationMethod": "center", + "notificationRecurrence": "beginning" + } + ] + } + }, + { + "id": "storageDetection-1", + "eventType": "storageDetection", + "eventDescription": "storageDetection Event trigger Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": null + }, + { + "id": "faceSnap-1", + "eventType": "faceSnap", + "eventDescription": "faceSnap Event trigger Information", + "videoInputChannelID": "1", + "dynVideoInputChannelID": "1", + "EventTriggerNotificationList": null + } + ] + } + } + }, + "Event/triggers/scenechangedetection-1": { + "status_code": 403 + }, + "Event/notification/httpHosts": { + "response": { + "HttpHostNotificationList": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "HttpHostNotification": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "1", + "url": "/api/hikvision", + "protocolType": "HTTP", + "parameterFormatType": "XML", + "addressingFormatType": "ipaddress", + "ipAddress": "1.0.0.93", + "portNo": "80", + "userName": null, + "httpAuthenticationMethod": "none" + } + } + } + }, + "Streaming/channels/101": { + "response": { + "StreamingChannel": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "101", + "channelName": "Camera 01", + "enabled": "true", + "Transport": { + "maxPacketSize": "1000", + "ControlProtocolList": { + "ControlProtocol": [ + { + "streamingTransport": "RTSP" + }, + { + "streamingTransport": "HTTP" + }, + { + "streamingTransport": "SHTTP" + } + ] + }, + "Unicast": { + "enabled": "true", + "rtpTransportType": "RTP/TCP" + }, + "Multicast": { + "enabled": "true", + "destIPAddress": "0.0.0.0", + "videoDestPortNo": "8860", + "audioDestPortNo": "8862", + "FecInfo": { + "fecRatio": "0", + "fecDestPortNo": "8960" + } + }, + "Security": { + "enabled": "true", + "certificateType": "digest/basic" + } + }, + "Video": { + "enabled": "true", + "videoInputChannelID": "1", + "videoCodecType": "H.265", + "videoScanType": "progressive", + "videoResolutionWidth": "2688", + "videoResolutionHeight": "1520", + "videoQualityControlType": "VBR", + "constantBitRate": "3072", + "fixedQuality": "60", + "vbrUpperCap": "3072", + "vbrLowerCap": "32", + "maxFrameRate": "2500", + "keyFrameInterval": "2000", + "snapShotImageType": "JPEG", + "GovLength": "50", + "SVC": { + "enabled": "false" + }, + "PacketType": ["PS", "RTP"], + "smoothing": "50", + "H265Profile": "Main", + "SmartCodec": { + "enabled": "true" + }, + "vbrAverageCap": "1536" + }, + "Audio": { + "enabled": "false", + "audioInputChannelID": "1", + "audioCompressionType": "G.711ulaw" + } + } + } + }, + "Streaming/channels/102": { + "response": { + "StreamingChannel": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "102", + "channelName": "Camera 01", + "enabled": "true", + "Transport": { + "maxPacketSize": "1000", + "ControlProtocolList": { + "ControlProtocol": [ + { + "streamingTransport": "RTSP" + }, + { + "streamingTransport": "HTTP" + }, + { + "streamingTransport": "SHTTP" + } + ] + }, + "Unicast": { + "enabled": "true", + "rtpTransportType": "RTP/TCP" + }, + "Multicast": { + "enabled": "true", + "destIPAddress": "0.0.0.0", + "videoDestPortNo": "8866", + "audioDestPortNo": "8868", + "FecInfo": { + "fecRatio": "0", + "fecDestPortNo": "8966" + } + }, + "Security": { + "enabled": "true", + "certificateType": "digest/basic" + } + }, + "Video": { + "enabled": "true", + "videoInputChannelID": "1", + "videoCodecType": "H.265", + "videoScanType": "progressive", + "videoResolutionWidth": "640", + "videoResolutionHeight": "480", + "videoQualityControlType": "VBR", + "constantBitRate": "256", + "fixedQuality": "60", + "vbrUpperCap": "256", + "vbrLowerCap": "32", + "maxFrameRate": "1000", + "keyFrameInterval": "5000", + "snapShotImageType": "JPEG", + "GovLength": "50", + "SVC": { + "enabled": "false" + }, + "PacketType": ["PS", "RTP"], + "smoothing": "50", + "H265Profile": "Main" + }, + "Audio": { + "enabled": "false", + "audioInputChannelID": "1", + "audioCompressionType": "G.711ulaw" + } + } + } + }, + "Streaming/channels/103": { + "response": { + "StreamingChannel": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "103", + "channelName": "Camera 01", + "enabled": "true", + "Transport": { + "maxPacketSize": "1000", + "ControlProtocolList": { + "ControlProtocol": [ + { + "streamingTransport": "RTSP" + }, + { + "streamingTransport": "HTTP" + }, + { + "streamingTransport": "SHTTP" + } + ] + }, + "Unicast": { + "enabled": "true", + "rtpTransportType": "RTP/TCP" + }, + "Multicast": { + "enabled": "true", + "destIPAddress": "0.0.0.0", + "videoDestPortNo": "8860", + "audioDestPortNo": "8862", + "FecInfo": { + "fecRatio": "0", + "fecDestPortNo": "8960" + } + }, + "Security": { + "enabled": "true", + "certificateType": "digest/basic" + } + }, + "Video": { + "enabled": "true", + "videoInputChannelID": "1", + "videoCodecType": "H.265", + "videoScanType": "progressive", + "videoResolutionWidth": "2688", + "videoResolutionHeight": "1520", + "videoQualityControlType": "VBR", + "constantBitRate": "3072", + "fixedQuality": "60", + "vbrUpperCap": "3072", + "vbrLowerCap": "32", + "maxFrameRate": "2500", + "keyFrameInterval": "2000", + "snapShotImageType": "JPEG", + "GovLength": "50", + "SVC": { + "enabled": "false" + }, + "PacketType": ["PS", "RTP"], + "smoothing": "50", + "H265Profile": "Main", + "SmartCodec": { + "enabled": "true" + }, + "vbrAverageCap": "1536" + }, + "Audio": { + "enabled": "false", + "audioInputChannelID": "1", + "audioCompressionType": "G.711ulaw" + } + } + } + }, + "Streaming/channels/104": { + "response": { + "StreamingChannel": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "104", + "channelName": "Camera 01", + "enabled": "true", + "Transport": { + "maxPacketSize": "1000", + "ControlProtocolList": { + "ControlProtocol": [ + { + "streamingTransport": "RTSP" + }, + { + "streamingTransport": "HTTP" + }, + { + "streamingTransport": "SHTTP" + } + ] + }, + "Unicast": { + "enabled": "true", + "rtpTransportType": "RTP/TCP" + }, + "Multicast": { + "enabled": "true", + "destIPAddress": "0.0.0.0", + "videoDestPortNo": "8860", + "audioDestPortNo": "8862", + "FecInfo": { + "fecRatio": "0", + "fecDestPortNo": "8960" + } + }, + "Security": { + "enabled": "true", + "certificateType": "digest/basic" + } + }, + "Video": { + "enabled": "true", + "videoInputChannelID": "1", + "videoCodecType": "H.265", + "videoScanType": "progressive", + "videoResolutionWidth": "2688", + "videoResolutionHeight": "1520", + "videoQualityControlType": "VBR", + "constantBitRate": "3072", + "fixedQuality": "60", + "vbrUpperCap": "3072", + "vbrLowerCap": "32", + "maxFrameRate": "2500", + "keyFrameInterval": "2000", + "snapShotImageType": "JPEG", + "GovLength": "50", + "SVC": { + "enabled": "false" + }, + "PacketType": ["PS", "RTP"], + "smoothing": "50", + "H265Profile": "Main", + "SmartCodec": { + "enabled": "true" + }, + "vbrAverageCap": "1536" + }, + "Audio": { + "enabled": "false", + "audioInputChannelID": "1", + "audioCompressionType": "G.711ulaw" + } + } + } + }, + "System/Video/inputs/channels/1/motionDetection": { + "response": { + "MotionDetection": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "enabled": "false", + "enableHighlight": "false", + "samplingInterval": "2", + "startTriggerTime": "500", + "endTriggerTime": "500", + "regionType": "grid", + "Grid": { + "rowGranularity": "18", + "columnGranularity": "22" + }, + "MotionDetectionLayout": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "sensitivityLevel": "0", + "layout": { + "gridMap": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + } + } + } + }, + "System/Video/inputs/channels/1/tamperDetection": { + "response": { + "TamperDetection": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "enabled": "false", + "normalizedScreenSize": { + "normalizedScreenWidth": "704", + "normalizedScreenHeight": "576" + }, + "TamperDetectionRegionList": { + "TamperDetectionRegion": { + "id": "0", + "enabled": "false", + "sensitivityLevel": "30", + "RegionCoordinatesList": null + } + } + } + } + }, + "Smart/LineDetection/1": { + "response": { + "LineDetection": { + "id": "1", + "enabled": "false", + "normalizedScreenSize": { + "normalizedScreenWidth": "1000", + "normalizedScreenHeight": "1000" + }, + "LineItemList": { + "@size": "1", + "LineItem": { + "id": "1", + "enabled": "false", + "sensitivityLevel": "50", + "directionSensitivity": "any", + "CoordinatesList": { + "Coordinates": [ + { + "positionX": "0", + "positionY": "1000" + }, + { + "positionX": "0", + "positionY": "1000" + } + ] + } + } + }, + "isSupportMultiScene": "false", + "recogRuleType": "vectorMode" + } + } + }, + "Smart/FieldDetection/1": { + "response": { + "FieldDetection": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "1", + "enabled": "false", + "startTriggerTime": "500", + "endTriggerTime": "500", + "normalizedScreenSize": { + "normalizedScreenWidth": "1000", + "normalizedScreenHeight": "1000" + }, + "FieldDetectionRegionList": { + "@size": "1", + "FieldDetectionRegion": { + "@version": "2.0", + "@xmlns": "http://www.hikvision.com/ver20/XMLSchema", + "id": "1", + "enabled": "false", + "sensitivityLevel": "50", + "timeThreshold": "0", + "RegionCoordinatesList": null + } + }, + "isSupportMultiScene": "false" + } + } + }, + "WLAlarm/PIR": { + "response": { + "PIRAlarm": { + "@version": "1.0", + "@xmlns": "http://www.hikvision.com/ver10/XMLSchema", + "enabled": "true", + "name": "PIR Alarm" + } + } + } + } + } +} diff --git a/tests/test_init.py b/tests/test_init.py index 61a68fb..c9aa331 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -9,6 +9,25 @@ from tests.conftest import TEST_CONFIG, TEST_CONFIG_WITH_ALARM_SERVER +@pytest.mark.parametrize("init_integration", +[ + "DS-7608NXI-I2", + "DS-2CD2386G2-IU", + "DS-2CD2146G2-ISU", + "DS-2CD2443G0-IW", + "DS-7616NI-Q2" +], indirect=True) +async def test_basic_init(hass: HomeAssistant, init_integration: MockConfigEntry) -> None: + """Test a successful setup entry.""" + + entry = init_integration + assert entry.state == ConfigEntryState.LOADED + + isapi = hass.data[DOMAIN][entry.entry_id]["isapi"] + assert isapi.host == TEST_CONFIG["host"] + assert init_integration.title in isapi.device_info.model + + @pytest.mark.parametrize("init_integration", ["DS-7608NXI-I2"], indirect=True) async def test_async_setup_entry_nvr(hass: HomeAssistant, init_integration: MockConfigEntry) -> None: """Test a successful NVR setup entry.""" diff --git a/tests/test_pir.py b/tests/test_pir.py new file mode 100644 index 0000000..b235762 --- /dev/null +++ b/tests/test_pir.py @@ -0,0 +1,75 @@ +"""Tests for PIR sensor.""" + +import respx +import pytest +from http import HTTPStatus +from homeassistant.core import HomeAssistant +from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN +from pytest_homeassistant_custom_component.common import MockConfigEntry +import homeassistant.helpers.entity_registry as er +from custom_components.hikvision_next.notifications import EventNotificationsView +from tests.test_notifications import mock_event_notification +from tests.conftest import TEST_CONFIG +from homeassistant.const import ( + ATTR_ENTITY_ID, + SERVICE_TURN_OFF, + STATE_ON, + STATE_OFF +) + +@pytest.mark.parametrize("init_integration", ["DS-2CD2443G0-IW"], indirect=True) +async def test_pir_entities( + hass: HomeAssistant, + init_integration: MockConfigEntry, +) -> None: + """Test PIR entities creation """ + + entities = [ + "binary_sensor.ds_2cd2443g0_iw00000000aawre00000000_1_pir", + "switch.ds_2cd2443g0_iw00000000aawre00000000_1_pir" + ] + + entity_registry = er.async_get(hass) + for entity_id in entities: + assert (entity := entity_registry.async_get(entity_id)) + assert not entity.disabled + + +@pytest.mark.parametrize("init_integration", ["DS-2CD2443G0-IW"], indirect=True) +async def test_pir_alert( + hass: HomeAssistant, init_integration: MockConfigEntry, +) -> None: + """Test incoming PIR alarm.""" + + entity_id = "binary_sensor.ds_2cd2443g0_iw00000000aawre00000000_1_pir" + assert (sensor := hass.states.get(entity_id)) + assert sensor.state == STATE_OFF + + view = EventNotificationsView(hass) + mock_request = mock_event_notification("pir") + response = await view.post(mock_request) + + assert response.status == HTTPStatus.OK + assert (sensor := hass.states.get(entity_id)) + assert sensor.state == STATE_ON + + +@pytest.mark.parametrize("init_integration", ["DS-2CD2443G0-IW"], indirect=True) +async def test_pir_switch(hass: HomeAssistant, init_integration: MockConfigEntry) -> None: + """Test PIR switch.""" + + entity_id = "switch.ds_2cd2443g0_iw00000000aawre00000000_1_pir" + assert (switch := hass.states.get(entity_id)) + assert switch.state == STATE_ON + + url = f"{TEST_CONFIG['host']}/ISAPI/WLAlarm/PIR" + endpoint = respx.put(url) + + # switch to off + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: entity_id}, + blocking=True, + ) + assert endpoint.called