From 6b624f0e1cb2dd8391c565ab56d0fba3814e742a Mon Sep 17 00:00:00 2001 From: Matthew Skinner Date: Thu, 25 Feb 2021 04:07:48 +1100 Subject: [PATCH] [ipcamera] Improve Dahua alarms (#10078) Signed-off-by: Matthew Skinner --- .../org.openhab.binding.ipcamera/README.md | 5 + .../ipcamera/internal/DahuaHandler.java | 231 ++++++++++++------ .../ipcamera/internal/DoorBirdHandler.java | 8 +- .../ipcamera/internal/FoscamHandler.java | 8 +- .../internal/IpCameraBindingConstants.java | 2 + .../ipcamera/internal/MyNettyAuthHandler.java | 7 +- .../handler/IpCameraGroupHandler.java | 2 +- .../internal/handler/IpCameraHandler.java | 35 ++- .../internal/onvif/OnvifDiscovery.java | 4 +- .../resources/OH-INF/thing/thing-types.xml | 21 ++ 10 files changed, 230 insertions(+), 93 deletions(-) diff --git a/bundles/org.openhab.binding.ipcamera/README.md b/bundles/org.openhab.binding.ipcamera/README.md index fd826ff21..44ad00c73 100644 --- a/bundles/org.openhab.binding.ipcamera/README.md +++ b/bundles/org.openhab.binding.ipcamera/README.md @@ -213,6 +213,7 @@ The channels are kept consistent as much as possible from brand to brand to make | `activateAlarmOutput2` | Switch | Toggles a cameras relay output 2. | | `audioAlarm` | Switch (read only) | When the camera detects noise above a threshold this switch will move to ON. | | `autoLED` | Switch | When ON this sets a cameras IR LED to automatically turn on or off. | +| `carAlarm` | Switch | When a car is detected the switch will turn ON. | | `cellMotionAlarm` | Switch (read only) | ONVIF cameras only will reflect the status of the ONVIF event of the same name. | | `doorBell` | Switch (read only) | Doorbird only, will reflect the status of the doorbell button. | | `enableAudioAlarm` | Switch | Allows the audio alarm to be turned ON or OFF. | @@ -234,6 +235,7 @@ The channels are kept consistent as much as possible from brand to brand to make | `gifHistoryLength` | Number | How many filenames are in the `gifHistory`. | | `gotoPreset` | String | ONVIF cameras that can move only. Will cause the camera to move to a preset location. | | `hlsUrl` | String | The URL for the ipcamera.m3u8 file. | +| `humanAlarm` | Switch | When a camera detects a human this switch will turn ON. | | `imageUrl` | String | The URL for the ipcamera.jpg file. | | `itemLeft` | Switch (read only) | Will turn ON if an API camera detects an item has been left behind. | | `itemTaken` | Switch (read only) | Will turn ON if an API camera detects an item has been stolen. | @@ -379,6 +381,9 @@ See this forum thread for examples of how to use snapshots and streams in a site ## Video Streams +To get video streams working, this forum thread has working widget examples that you can use. + + To get some of the video formats working, you need to install FFmpeg. Visit their site here to learn how diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DahuaHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DahuaHandler.java index 19daffebc..65234b506 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DahuaHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DahuaHandler.java @@ -14,7 +14,7 @@ package org.openhab.binding.ipcamera.internal; import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.*; -import java.util.ArrayList; +import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -48,6 +48,150 @@ public class DahuaHandler extends ChannelDuplexHandler { this.nvrChannel = nvrChannel; } + private void processEvent(String content) { + int startIndex = content.indexOf("Code=", 12) + 5;// skip --myboundary + int endIndex = content.indexOf(";", startIndex + 1); + if (startIndex == -1 || endIndex == -1) { + ipCameraHandler.logger.debug("Code= not found in Dahua event. Content was:{}", content); + return; + } + String code = content.substring(startIndex, endIndex); + startIndex = endIndex + 8;// skip ;action= + endIndex = content.indexOf(";", startIndex); + if (startIndex == -1 || endIndex == -1) { + ipCameraHandler.logger.debug(";action= not found in Dahua event. Content was:{}", content); + return; + } + String action = content.substring(startIndex, endIndex); + switch (code) { + case "VideoMotion": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM); + } + break; + case "TakenAwayDetection": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_ITEM_TAKEN); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_ITEM_TAKEN); + } + break; + case "LeftDetection": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_ITEM_LEFT); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_ITEM_LEFT); + } + break; + case "SmartMotionVehicle": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_CAR_ALARM); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_CAR_ALARM); + } + break; + case "SmartMotionHuman": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_HUMAN_ALARM); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_HUMAN_ALARM); + } + break; + case "CrossLineDetection": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_LINE_CROSSING_ALARM); + } + break; + case "AudioMutation": + if (action.equals("Start")) { + ipCameraHandler.audioDetected(); + } else if (action.equals("Stop")) { + ipCameraHandler.noAudioDetected(); + } + break; + case "FaceDetection": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_FACE_DETECTED); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_FACE_DETECTED); + } + break; + case "ParkingDetection": + if (action.equals("Start")) { + ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.ON); + } else if (action.equals("Stop")) { + ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.OFF); + } + break; + case "CrossRegionDetection": + if (action.equals("Start")) { + ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM); + } else if (action.equals("Stop")) { + ipCameraHandler.noMotionDetected(CHANNEL_FIELD_DETECTION_ALARM); + } + break; + case "VideoLoss": + case "VideoBlind": + if (action.equals("Start")) { + ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.ON); + } else if (action.equals("Stop")) { + ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.OFF); + } + break; + case "VideoAbnormalDetection": + if (action.equals("Start")) { + ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.ON); + } else if (action.equals("Stop")) { + ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.OFF); + } + break; + case "VideoUnFocus": + if (action.equals("Start")) { + ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.ON); + } else if (action.equals("Stop")) { + ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.OFF); + } + break; + case "AlarmLocal": + if (action.equals("Start")) { + if (content.contains("index=0")) { + ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.ON); + } else { + ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.ON); + } + } else if (action.equals("Stop")) { + if (content.contains("index=0")) { + ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.OFF); + } else { + ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.OFF); + } + } + break; + case "LensMaskOpen": + ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.ON); + break; + case "LensMaskClose": + ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF); + break; + case "TimeChange": + case "NTPAdjustTime": + case "StorageChange": + case "Reboot": + case "NewFile": + case "VideoMotionInfo": + case "RtspSessionDisconnect": + case "LeFunctionStatusSync": + case "RecordDelete": + break; + default: + ipCameraHandler.logger.debug("Unrecognised Dahua event, Code={}, action={}", code, action); + } + } + // This handles the incoming http replies back from the camera. @Override public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception { @@ -56,6 +200,10 @@ public class DahuaHandler extends ChannelDuplexHandler { } try { String content = msg.toString(); + if (content.startsWith("--myboundary")) { + processEvent(content); + return; + } ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content); // determine if the motion detection is turned on or off. if (content.contains("table.MotionDetect[0].Enable=true")) { @@ -63,77 +211,20 @@ public class DahuaHandler extends ChannelDuplexHandler { } else if (content.contains("table.MotionDetect[" + nvrChannel + "].Enable=false")) { ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.OFF); } - // Handle motion alarm - if (content.contains("Code=VideoMotion;action=Start;index=0")) { - ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM); - } else if (content.contains("Code=VideoMotion;action=Stop;index=0")) { - ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM); - } - // Handle item taken alarm - if (content.contains("Code=TakenAwayDetection;action=Start;index=0")) { - ipCameraHandler.motionDetected(CHANNEL_ITEM_TAKEN); - } else if (content.contains("Code=TakenAwayDetection;action=Stop;index=0")) { - ipCameraHandler.noMotionDetected(CHANNEL_ITEM_TAKEN); - } - // Handle item left alarm - if (content.contains("Code=LeftDetection;action=Start;index=0")) { - ipCameraHandler.motionDetected(CHANNEL_ITEM_LEFT); - } else if (content.contains("Code=LeftDetection;action=Stop;index=0")) { - ipCameraHandler.noMotionDetected(CHANNEL_ITEM_LEFT); - } - // Handle CrossLineDetection alarm - if (content.contains("Code=CrossLineDetection;action=Start;index=0")) { - ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM); - } else if (content.contains("Code=CrossLineDetection;action=Stop;index=0")) { - ipCameraHandler.noMotionDetected(CHANNEL_LINE_CROSSING_ALARM); - } + // determine if the audio alarm is turned on or off. if (content.contains("table.AudioDetect[0].MutationDetect=true")) { ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON); } else if (content.contains("table.AudioDetect[0].MutationDetect=false")) { ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.OFF); } - // Handle AudioMutation alarm - if (content.contains("Code=AudioMutation;action=Start;index=0")) { - ipCameraHandler.audioDetected(); - } else if (content.contains("Code=AudioMutation;action=Stop;index=0")) { - ipCameraHandler.noAudioDetected(); - } + // Handle AudioMutationThreshold alarm if (content.contains("table.AudioDetect[0].MutationThreold=")) { String value = ipCameraHandler.returnValueFromString(content, "table.AudioDetect[0].MutationThreold="); ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.valueOf(value)); } - // Handle FaceDetection alarm - if (content.contains("Code=FaceDetection;action=Start;index=0")) { - ipCameraHandler.motionDetected(CHANNEL_FACE_DETECTED); - } else if (content.contains("Code=FaceDetection;action=Stop;index=0")) { - ipCameraHandler.noMotionDetected(CHANNEL_FACE_DETECTED); - } - // Handle ParkingDetection alarm - if (content.contains("Code=ParkingDetection;action=Start;index=0")) { - ipCameraHandler.motionDetected(CHANNEL_PARKING_ALARM); - } else if (content.contains("Code=ParkingDetection;action=Stop;index=0")) { - ipCameraHandler.noMotionDetected(CHANNEL_PARKING_ALARM); - } - // Handle CrossRegionDetection alarm - if (content.contains("Code=CrossRegionDetection;action=Start;index=0")) { - ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM); - } else if (content.contains("Code=CrossRegionDetection;action=Stop;index=0")) { - ipCameraHandler.noMotionDetected(CHANNEL_FIELD_DETECTION_ALARM); - } - // Handle External Input alarm - if (content.contains("Code=AlarmLocal;action=Start;index=0")) { - ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.ON); - } else if (content.contains("Code=AlarmLocal;action=Stop;index=0")) { - ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.OFF); - } - // Handle External Input alarm2 - if (content.contains("Code=AlarmLocal;action=Start;index=1")) { - ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.ON); - } else if (content.contains("Code=AlarmLocal;action=Stop;index=1")) { - ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.OFF); - } + // CrossLineDetection alarm on/off if (content.contains("table.VideoAnalyseRule[0][1].Enable=true")) { ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.ON); @@ -141,10 +232,9 @@ public class DahuaHandler extends ChannelDuplexHandler { ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.OFF); } // Privacy Mode on/off - if (content.contains("Code=LensMaskOpen;") || content.contains("table.LeLensMask[0].Enable=true")) { + if (content.contains("table.LeLensMask[0].Enable=true")) { ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.ON); - } else if (content.contains("Code=LensMaskClose;") - || content.contains("table.LeLensMask[0].Enable=false")) { + } else if (content.contains("table.LeLensMask[0].Enable=false")) { ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF); } } finally { @@ -152,13 +242,10 @@ public class DahuaHandler extends ChannelDuplexHandler { } } - // This handles the commands that come from the Openhab event bus. + // This handles the commands that come from the openHAB event bus. public void handleCommand(ChannelUID channelUID, Command command) { if (command instanceof RefreshType) { switch (channelUID.getId()) { - case CHANNEL_THRESHOLD_AUDIO_ALARM: - // ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=AudioDetect[0]"); - return; case CHANNEL_ENABLE_AUDIO_ALARM: ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=AudioDetect[0]"); return; @@ -172,8 +259,7 @@ public class DahuaHandler extends ChannelDuplexHandler { ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=LeLensMask[0]"); return; } - return; // Return as we have handled the refresh command above and don't need to - // continue further. + return; } // end of "REFRESH" switch (channelUID.getId()) { case CHANNEL_TEXT_OVERLAY: @@ -272,8 +358,7 @@ public class DahuaHandler extends ChannelDuplexHandler { // If a camera does not need to poll a request as often as snapshots, it can be // added here. Binding steps through the list. - public ArrayList getLowPriorityRequests() { - ArrayList lowPriorityRequests = new ArrayList(1); - return lowPriorityRequests; + public List getLowPriorityRequests() { + return List.of(); } } diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DoorBirdHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DoorBirdHandler.java index c23295b76..f6ab9bc8d 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DoorBirdHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DoorBirdHandler.java @@ -53,16 +53,14 @@ public class DoorBirdHandler extends ChannelDuplexHandler { try { String content = msg.toString(); ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content); - if (content.contains("doorbell:H")) { - ipCameraHandler.setChannelState(CHANNEL_DOORBELL, OnOffType.ON); - } if (content.contains("doorbell:L")) { ipCameraHandler.setChannelState(CHANNEL_DOORBELL, OnOffType.OFF); + } else if (content.contains("doorbell:H")) { + ipCameraHandler.setChannelState(CHANNEL_DOORBELL, OnOffType.ON); } if (content.contains("motionsensor:L")) { ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM); - } - if (content.contains("motionsensor:H")) { + } else if (content.contains("motionsensor:H")) { ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM); } } finally { diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/FoscamHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/FoscamHandler.java index d85680b7f..ff314392e 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/FoscamHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/FoscamHandler.java @@ -14,7 +14,7 @@ package org.openhab.binding.ipcamera.internal; import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.*; -import java.util.ArrayList; +import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -212,9 +212,7 @@ public class FoscamHandler extends ChannelDuplexHandler { // If a camera does not need to poll a request as often as snapshots, it can be // added here. Binding steps through the list. - public ArrayList getLowPriorityRequests() { - ArrayList lowPriorityRequests = new ArrayList(1); - lowPriorityRequests.add("/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=" + username + "&pwd=" + password); - return lowPriorityRequests; + public List getLowPriorityRequests() { + return List.of(); } } 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 e01c7118a..475f91a53 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 @@ -129,4 +129,6 @@ public class IpCameraBindingConstants { public static final String CHANNEL_GOTO_PRESET = "gotoPreset"; public static final String CHANNEL_START_STREAM = "startStream"; 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"; } 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 58386308e..e59b4055f 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 @@ -95,7 +95,6 @@ public class MyNettyAuthHandler extends ChannelDuplexHandler { nonce = Helper.searchString(authenticate, "nonce=\""); opaque = Helper.searchString(authenticate, "opaque=\""); qop = Helper.searchString(authenticate, "qop=\""); - if (!qop.isEmpty() && !realm.isEmpty()) { ipCameraHandler.useDigestAuth = true; } else { @@ -128,8 +127,10 @@ public class MyNettyAuthHandler extends ChannelDuplexHandler { String digestString = "username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + requestURI + "\", cnonce=\"" + cnonce + "\", nc=" + nc + ", qop=\"" + qop + "\", response=\"" - + response + "\", opaque=\"" + opaque + "\""; - + + response + "\""; + if (!opaque.isEmpty()) { + digestString += ", opaque=\"" + opaque + "\""; + } if (reSend) { ipCameraHandler.sendHttpRequest(httpMethod, requestURI, digestString); return; diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraGroupHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraGroupHandler.java index 6d2ffe076..c089e7768 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraGroupHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraGroupHandler.java @@ -353,7 +353,7 @@ public class IpCameraGroupHandler extends BaseThingHandler { startStreamServer(true); } updateStatus(ThingStatus.ONLINE); - pollCameraGroupJob = pollCameraGroup.scheduleAtFixedRate(this::pollCameraGroup, 10000, + pollCameraGroupJob = pollCameraGroup.scheduleWithFixedDelay(this::pollCameraGroup, 10000, groupConfig.getPollTime(), TimeUnit.MILLISECONDS); } 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 ea43387e1..09a59477f 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 @@ -591,8 +591,8 @@ public class IpCameraHandler extends BaseThingHandler { } logger.trace("Sending camera: {}: http://{}:{}{}", httpMethod, cameraConfig.getIp(), port, httpRequestURL); - channelTrackingMap.put(httpRequestURL, new ChannelTracking(ch, httpRequestURL)); + openChannel(ch, httpRequestURL); CommonCameraHandler commonHandler = (CommonCameraHandler) ch.pipeline().get(COMMON_HANDLER); commonHandler.setURL(httpRequestURLFull); MyNettyAuthHandler authHandler = (MyNettyAuthHandler) ch.pipeline().get(AUTH_HANDLER); @@ -782,6 +782,15 @@ public class IpCameraHandler extends BaseThingHandler { } } + void openChannel(Channel channel, String httpRequestURL) { + ChannelTracking tracker = channelTrackingMap.get(httpRequestURL); + if (tracker != null && !tracker.getReply().isEmpty()) {// We need to keep the stored reply + tracker.setChannel(channel); + return; + } + channelTrackingMap.put(httpRequestURL, new ChannelTracking(channel, httpRequestURL)); + } + void closeChannel(String url) { ChannelTracking channelTracking = channelTrackingMap.get(url); if (channelTracking != null) { @@ -1412,9 +1421,22 @@ public class IpCameraHandler extends BaseThingHandler { localFuture.cancel(false); } + switch (thing.getThingTypeUID().getId()) { + case HIKVISION_THING: + sendHttpGET("/ISAPI/Smart/AudioDetection/channels/" + cameraConfig.getNvrChannel() + "01"); + sendHttpGET("/ISAPI/Smart/LineDetection/" + cameraConfig.getNvrChannel() + "01"); + sendHttpGET("/ISAPI/Smart/FieldDetection/" + cameraConfig.getNvrChannel() + "01"); + sendHttpGET( + "/ISAPI/System/Video/inputs/channels/" + cameraConfig.getNvrChannel() + "01/motionDetection"); + sendHttpGET("/ISAPI/System/Video/inputs/channels/" + cameraConfig.getNvrChannel() + "/overlays/text/1"); + sendHttpGET("/ISAPI/System/IO/inputs/" + cameraConfig.getNvrChannel()); + sendHttpGET("/ISAPI/System/IO/inputs/" + cameraConfig.getNvrChannel()); + break; + } + if (cameraConfig.getGifPreroll() > 0 || cameraConfig.getUpdateImageWhen().contains("1")) { snapshotPolling = true; - snapshotJob = threadPool.scheduleAtFixedRate(this::snapshotRunnable, 1000, cameraConfig.getPollTime(), + snapshotJob = threadPool.scheduleWithFixedDelay(this::snapshotRunnable, 1000, cameraConfig.getPollTime(), TimeUnit.MILLISECONDS); } @@ -1537,11 +1559,11 @@ public class IpCameraHandler extends BaseThingHandler { } if (streamingSnapshotMjpeg || streamingAutoFps) { snapshotPolling = true; - snapshotJob = threadPool.scheduleAtFixedRate(this::snapshotRunnable, 200, cameraConfig.getPollTime(), + snapshotJob = threadPool.scheduleWithFixedDelay(this::snapshotRunnable, 200, cameraConfig.getPollTime(), TimeUnit.MILLISECONDS); } else if (cameraConfig.getUpdateImageWhen().contains("4")) { // During Motion Alarms snapshotPolling = true; - snapshotJob = threadPool.scheduleAtFixedRate(this::snapshotRunnable, 200, cameraConfig.getPollTime(), + snapshotJob = threadPool.scheduleWithFixedDelay(this::snapshotRunnable, 200, cameraConfig.getPollTime(), TimeUnit.MILLISECONDS); } } @@ -1610,6 +1632,10 @@ public class IpCameraHandler extends BaseThingHandler { sendHttpGET("/bha-api/monitor.cgi?ring=doorbell,motionsensor"); } break; + case FOSCAM_THING: + sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=" + cameraConfig.getUser() + "&pwd=" + + cameraConfig.getPassword()); + break; } Ffmpeg localHLS = ffmpegHLS; if (localHLS != null) { @@ -1747,6 +1773,7 @@ public class IpCameraHandler extends BaseThingHandler { Ffmpeg localFfmpeg = ffmpegHLS; if (localFfmpeg != null) { localFfmpeg.stopConverting(); + localFfmpeg = null; } localFfmpeg = ffmpegRecord; if (localFfmpeg != null) { diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifDiscovery.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifDiscovery.java index 10c744c81..170573315 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifDiscovery.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifDiscovery.java @@ -124,9 +124,9 @@ public class OnvifDiscovery { void processCameraReplys() { for (DatagramPacket packet : listOfReplys) { - logger.trace("Device replied to discovery with:{}", packet.toString()); String xml = packet.content().toString(CharsetUtil.UTF_8); - String xAddr = Helper.fetchXML(xml, "", ""); + logger.trace("Device replied to discovery with:{}", xml); + String xAddr = Helper.fetchXML(xml, "", "d:XAddrs>");// Foscam and all other brands if (!xAddr.equals("")) { searchReply(xAddr, xml); } else if (xml.contains("onvif")) { 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 1e354d4a3..12624ebc1 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 @@ -936,6 +936,11 @@ + + + + + @@ -2542,6 +2547,22 @@ + + Switch + + A person has triggered the Human Detection. + Alarm + + + + + Switch + + A car has triggered the Vehicle Detection. + Alarm + + + Switch