From ea134d8215e9a6a85907641cb446c91d92e81243 Mon Sep 17 00:00:00 2001 From: Matthew Skinner Date: Sat, 26 Nov 2022 18:15:29 +1100 Subject: [PATCH] [ipcamera] Improve support for newer 2k+ Instar cameras (#13773) * Fix never ending WARN when HIK camera does not support alarm inputs. * Streamline code. * Update Instar support for 2k+ Generation. * Fix alarm codes. * Add CHANNEL_LAST_EVENT_DATA Signed-off-by: Matthew Skinner --- .../org.openhab.binding.ipcamera/README.md | 2 +- .../ipcamera/internal/InstarHandler.java | 51 ++++++++++++++----- .../internal/IpCameraBindingConstants.java | 1 + .../ipcamera/internal/MyNettyAuthHandler.java | 2 +- .../internal/handler/IpCameraHandler.java | 16 ++++-- .../resources/OH-INF/thing/thing-types.xml | 12 +++++ 6 files changed, 67 insertions(+), 17 deletions(-) diff --git a/bundles/org.openhab.binding.ipcamera/README.md b/bundles/org.openhab.binding.ipcamera/README.md index 037163166d..1828b92581 100644 --- a/bundles/org.openhab.binding.ipcamera/README.md +++ b/bundles/org.openhab.binding.ipcamera/README.md @@ -167,7 +167,7 @@ If you do not specify any of these, the binding will use the default which shoul |-|-| | `ipAddress`| The IP address or host name of your camera. | | `port`| This port will be used for HTTP calls for fetching the snapshot and any API calls. | -| `onvifPort`| The port your camera uses for ONVIF connections. This is needed for PTZ movement, events, and the auto discovery of RTSP and snapshot URLs. | +| `onvifPort`| The port your camera uses for ONVIF connections. This is needed for PTZ movement, events, and the auto discovery of RTSP and snapshot URLs. A value of 0 will prevent the binding from trying to connect to ONVIF. | | `username`| Leave blank if your camera does not use login details. | | `password`| Leave blank if your camera does not use login details. | | `onvifMediaProfile`| 0 (default) is your cameras Mainstream and the numbers above 0 are the substreams. Any auto discovered URLs will use the streams that this indicates. You can always override the URLs should you wish to use something different for one of them. | diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/InstarHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/InstarHandler.java index 64e7705ce4..4c3ff3cc86 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/InstarHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/InstarHandler.java @@ -185,26 +185,53 @@ public class InstarHandler extends ChannelDuplexHandler { } public void alarmTriggered(String alarm) { - ipCameraHandler.logger.debug("Alarm has been triggered:{}", alarm); - switch (alarm) { - case "/instar?&active=1":// The motion area boxes 1-4 - case "/instar?&active=2": - case "/instar?&active=3": - case "/instar?&active=4": + // older cameras placed the & for the first query, whilst newer cameras do not. + // examples are /instar?&active=6 vs /instar?active=6&object=0 + ipCameraHandler.setChannelState(CHANNEL_LAST_EVENT_DATA, new StringType(alarm)); + String alarmCode = alarm.replaceAll(".+active=", ""); + alarmCode = alarmCode.replaceAll("&.+", ""); + String objectCode = alarm.replaceAll(".+object=", ""); + switch (alarmCode) { + case "1":// The motion area boxes 1-4 + case "2": + case "3": + case "4": ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM); break; - case "/instar?&active=5":// PIR + case "5":// PIR ipCameraHandler.motionDetected(CHANNEL_PIR_ALARM); break; - case "/instar?&active=6":// Audio Alarm + case "6":// Audio Alarm ipCameraHandler.audioDetected(); break; - case "/instar?&active=7":// Motion Area 1 - case "/instar?&active=8":// Motion Area 2 - case "/instar?&active=9":// Motion Area 3 - case "/instar?&active=10":// Motion Area 4 + case "7":// Motion area 1 + PIR + case "8":// Motion area 2 + PIR + case "9":// Motion area 3 + PIR + case "10":// Motion area 4 + PIR ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM); + ipCameraHandler.motionDetected(CHANNEL_PIR_ALARM); break; + default: + ipCameraHandler.logger.debug("Unknown alarm code:{}", alarmCode); + } + if (!objectCode.isEmpty()) { + switch (objectCode) { + case "0":// no object + break; + case "1":// person/human + ipCameraHandler.motionDetected(CHANNEL_HUMAN_ALARM); + break; + case "2":// car/vehicles + ipCameraHandler.motionDetected(CHANNEL_CAR_ALARM); + break; + case "3":// animals + case "4": + case "5": + ipCameraHandler.motionDetected(CHANNEL_ANIMAL_ALARM); + break; + default: + ipCameraHandler.logger.debug("Unknown object detection code:{}", objectCode); + } } } diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/IpCameraBindingConstants.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/IpCameraBindingConstants.java index 678d1a1277..8ebbe96b5e 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/IpCameraBindingConstants.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/IpCameraBindingConstants.java @@ -138,4 +138,5 @@ public class IpCameraBindingConstants { public static final String CHANNEL_ENABLE_PRIVACY_MODE = "enablePrivacyMode"; public static final String CHANNEL_CAR_ALARM = "carAlarm"; public static final String CHANNEL_HUMAN_ALARM = "humanAlarm"; + public static final String CHANNEL_ANIMAL_ALARM = "animalAlarm"; } diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/MyNettyAuthHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/MyNettyAuthHandler.java index 615f9beb30..8d2a15dba6 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/MyNettyAuthHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/MyNettyAuthHandler.java @@ -74,7 +74,7 @@ public class MyNettyAuthHandler extends ChannelDuplexHandler { // First run it should not have authenticate as null // nonce is reused if authenticate is null so the NC needs to increment to allow this// public void processAuth(String authenticate, String httpMethod, String requestURI, boolean reSend) { - if (authenticate.contains("Basic realm=\"")) { + if (authenticate.contains("Basic realm=")) { if (ipCameraHandler.useDigestAuth) { // Possible downgrade authenticate attack avoided. return; diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java index 12b3daf2dc..cc6b8f5d22 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java @@ -1371,7 +1371,7 @@ public class IpCameraHandler extends BaseThingHandler { } return; } - if (!onvifCamera.isConnected()) { + if (cameraConfig.getOnvifPort() > 0 && !onvifCamera.isConnected()) { logger.debug("About to connect to the IP Camera using the ONVIF PORT at IP:{}:{}", cameraConfig.getIp(), cameraConfig.getOnvifPort()); onvifCamera.connect(thing.getThingTypeUID().getId().equals(ONVIF_THING)); @@ -1521,6 +1521,9 @@ public class IpCameraHandler extends BaseThingHandler { } noMotionDetected(CHANNEL_MOTION_ALARM); noMotionDetected(CHANNEL_PIR_ALARM); + noMotionDetected(CHANNEL_HUMAN_ALARM); + noMotionDetected(CHANNEL_CAR_ALARM); + noMotionDetected(CHANNEL_ANIMAL_ALARM); noAudioDetected(); break; case HIKVISION_THING: @@ -1639,11 +1642,18 @@ public class IpCameraHandler extends BaseThingHandler { if (mjpegUri.isEmpty()) { mjpegUri = "/mjpegstream.cgi?-chn=12"; } + // Newer Instar cameras use this to setup the Alarm Server + sendHttpGET( + "/param.cgi?cmd=setasaction&-server=1&enable=1&-interval=1&cmd=setasattr&-as_index=1&-as_server=" + + hostIp + "&-as_port=" + SERVLET_PORT + "&-as_path=/ipcamera/" + + getThing().getUID().getId() + + "/instar&-as_ssl=0&-as_insecure=0&-as_mode=0&-as_activequery=1&-as_auth=0&-as_query1=0&-as_query2=0&-as_query3=0&-as_query4=0&-as_query5=0"); + // Older Instar cameras use this to setup the Alarm Server sendHttpGET( "/param.cgi?cmd=setmdalarm&-aname=server2&-switch=on&-interval=1&cmd=setalarmserverattr&-as_index=3&-as_server=" + hostIp + "&-as_port=" + SERVLET_PORT + "&-as_path=/ipcamera/" + getThing().getUID().getId() - + "/instar&-as_queryattr1=&-as_queryval1=&-as_queryattr2=&-as_queryval2=&-as_queryattr3=&-as_queryval3=&-as_activequery=1&-as_auth=0&-as_query1=0&-as_query2=0&-as_query3=0"); + + "/instar&-as_ssl=0&-as_mode=1&-as_activequery=1&-as_auth=0&-as_query1=0&-as_query2=0&-as_query3=0&-as_query4=0&-as_query5=0"); break; } // for poll times 9 seconds and above don't display a warning about the Image channel. @@ -1658,7 +1668,7 @@ public class IpCameraHandler extends BaseThingHandler { private void tryConnecting() { if (!thing.getThingTypeUID().getId().equals(GENERIC_THING) - && !thing.getThingTypeUID().getId().equals(DOORBIRD_THING)) { + && !thing.getThingTypeUID().getId().equals(DOORBIRD_THING) && cameraConfig.getOnvifPort() > 0) { onvifCamera = new OnvifConnection(this, cameraConfig.getIp() + ":" + cameraConfig.getOnvifPort(), cameraConfig.getUser(), cameraConfig.getPassword()); onvifCamera.setSelectedMediaProfile(cameraConfig.getOnvifMediaProfile()); diff --git a/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml index 62090a3ff7..131f0a5132 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml @@ -2002,6 +2002,10 @@ + + + + @@ -2520,6 +2524,14 @@ + + Switch + + An animal has triggered the object detection. + Alarm + + + Switch -- 2.47.3