[ipcamera] Improve Dahua alarms (#10078)
Signed-off-by: Matthew Skinner <matt@pcmus.com>
This commit is contained in:
parent
7050a1478e
commit
6b624f0e1c
|
@ -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.
|
||||
<https://community.openhab.org/t/oh3-widget-building-a-camera-widget/110069>
|
||||
|
||||
To get some of the video formats working, you need to install FFmpeg.
|
||||
Visit their site here to learn how <https://ffmpeg.org/>
|
||||
|
||||
|
|
|
@ -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<String> getLowPriorityRequests() {
|
||||
ArrayList<String> lowPriorityRequests = new ArrayList<String>(1);
|
||||
return lowPriorityRequests;
|
||||
public List<String> getLowPriorityRequests() {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<String> getLowPriorityRequests() {
|
||||
ArrayList<String> lowPriorityRequests = new ArrayList<String>(1);
|
||||
lowPriorityRequests.add("/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=" + username + "&pwd=" + password);
|
||||
return lowPriorityRequests;
|
||||
public List<String> getLowPriorityRequests() {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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, "", "<d:XAddrs>");
|
||||
logger.trace("Device replied to discovery with:{}", xml);
|
||||
String xAddr = Helper.fetchXML(xml, "", "d:XAddrs>");// Foscam <wsdd:XAddrs> and all other brands <d:XAddrs>
|
||||
if (!xAddr.equals("")) {
|
||||
searchReply(xAddr, xml);
|
||||
} else if (xml.contains("onvif")) {
|
||||
|
|
|
@ -936,6 +936,11 @@
|
|||
<channel id="imageUrl" typeId="imageUrl"/>
|
||||
<channel id="hlsUrl" typeId="hlsUrl"/>
|
||||
<channel id="enablePrivacyMode" typeId="enablePrivacyMode"/>
|
||||
<channel id="carAlarm" typeId="carAlarm"/>
|
||||
<channel id="humanAlarm" typeId="humanAlarm"/>
|
||||
<channel id="tooDarkAlarm" typeId="tooDarkAlarm"/>
|
||||
<channel id="sceneChangeAlarm" typeId="sceneChangeAlarm"/>
|
||||
<channel id="tooBlurryAlarm" typeId="tooBlurryAlarm"/>
|
||||
</channels>
|
||||
<config-description>
|
||||
|
||||
|
@ -2542,6 +2547,22 @@
|
|||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="humanAlarm" advanced="true">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Human Alarm</label>
|
||||
<description>A person has triggered the Human Detection.</description>
|
||||
<category>Alarm</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="carAlarm" advanced="true">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Car Alarm</label>
|
||||
<description>A car has triggered the Vehicle Detection.</description>
|
||||
<category>Alarm</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="parkingAlarm" advanced="true">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Parking Alarm</label>
|
||||
|
|
Loading…
Reference in New Issue