[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. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| `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`. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| `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
|
## 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.
|
To get some of the video formats working, you need to install FFmpeg.
|
||||||
Visit their site here to learn how <https://ffmpeg.org/>
|
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 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.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
@ -48,6 +48,150 @@ public class DahuaHandler extends ChannelDuplexHandler {
|
|||||||
this.nvrChannel = nvrChannel;
|
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.
|
// This handles the incoming http replies back from the camera.
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception {
|
public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception {
|
||||||
@ -56,6 +200,10 @@ public class DahuaHandler extends ChannelDuplexHandler {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String content = msg.toString();
|
String content = msg.toString();
|
||||||
|
if (content.startsWith("--myboundary")) {
|
||||||
|
processEvent(content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content);
|
ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content);
|
||||||
// determine if the motion detection is turned on or off.
|
// determine if the motion detection is turned on or off.
|
||||||
if (content.contains("table.MotionDetect[0].Enable=true")) {
|
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")) {
|
} else if (content.contains("table.MotionDetect[" + nvrChannel + "].Enable=false")) {
|
||||||
ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.OFF);
|
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.
|
// determine if the audio alarm is turned on or off.
|
||||||
if (content.contains("table.AudioDetect[0].MutationDetect=true")) {
|
if (content.contains("table.AudioDetect[0].MutationDetect=true")) {
|
||||||
ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
|
ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
|
||||||
} else if (content.contains("table.AudioDetect[0].MutationDetect=false")) {
|
} else if (content.contains("table.AudioDetect[0].MutationDetect=false")) {
|
||||||
ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.OFF);
|
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
|
// Handle AudioMutationThreshold alarm
|
||||||
if (content.contains("table.AudioDetect[0].MutationThreold=")) {
|
if (content.contains("table.AudioDetect[0].MutationThreold=")) {
|
||||||
String value = ipCameraHandler.returnValueFromString(content, "table.AudioDetect[0].MutationThreold=");
|
String value = ipCameraHandler.returnValueFromString(content, "table.AudioDetect[0].MutationThreold=");
|
||||||
ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.valueOf(value));
|
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
|
// CrossLineDetection alarm on/off
|
||||||
if (content.contains("table.VideoAnalyseRule[0][1].Enable=true")) {
|
if (content.contains("table.VideoAnalyseRule[0][1].Enable=true")) {
|
||||||
ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.ON);
|
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);
|
ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.OFF);
|
||||||
}
|
}
|
||||||
// Privacy Mode on/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);
|
ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.ON);
|
||||||
} else if (content.contains("Code=LensMaskClose;")
|
} else if (content.contains("table.LeLensMask[0].Enable=false")) {
|
||||||
|| content.contains("table.LeLensMask[0].Enable=false")) {
|
|
||||||
ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF);
|
ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF);
|
||||||
}
|
}
|
||||||
} finally {
|
} 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) {
|
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||||
if (command instanceof RefreshType) {
|
if (command instanceof RefreshType) {
|
||||||
switch (channelUID.getId()) {
|
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:
|
case CHANNEL_ENABLE_AUDIO_ALARM:
|
||||||
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=AudioDetect[0]");
|
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=AudioDetect[0]");
|
||||||
return;
|
return;
|
||||||
@ -172,8 +259,7 @@ public class DahuaHandler extends ChannelDuplexHandler {
|
|||||||
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=LeLensMask[0]");
|
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=LeLensMask[0]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return; // Return as we have handled the refresh command above and don't need to
|
return;
|
||||||
// continue further.
|
|
||||||
} // end of "REFRESH"
|
} // end of "REFRESH"
|
||||||
switch (channelUID.getId()) {
|
switch (channelUID.getId()) {
|
||||||
case CHANNEL_TEXT_OVERLAY:
|
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
|
// If a camera does not need to poll a request as often as snapshots, it can be
|
||||||
// added here. Binding steps through the list.
|
// added here. Binding steps through the list.
|
||||||
public ArrayList<String> getLowPriorityRequests() {
|
public List<String> getLowPriorityRequests() {
|
||||||
ArrayList<String> lowPriorityRequests = new ArrayList<String>(1);
|
return List.of();
|
||||||
return lowPriorityRequests;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,16 +53,14 @@ public class DoorBirdHandler extends ChannelDuplexHandler {
|
|||||||
try {
|
try {
|
||||||
String content = msg.toString();
|
String content = msg.toString();
|
||||||
ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content);
|
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")) {
|
if (content.contains("doorbell:L")) {
|
||||||
ipCameraHandler.setChannelState(CHANNEL_DOORBELL, OnOffType.OFF);
|
ipCameraHandler.setChannelState(CHANNEL_DOORBELL, OnOffType.OFF);
|
||||||
|
} else if (content.contains("doorbell:H")) {
|
||||||
|
ipCameraHandler.setChannelState(CHANNEL_DOORBELL, OnOffType.ON);
|
||||||
}
|
}
|
||||||
if (content.contains("motionsensor:L")) {
|
if (content.contains("motionsensor:L")) {
|
||||||
ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
|
ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
|
||||||
}
|
} else if (content.contains("motionsensor:H")) {
|
||||||
if (content.contains("motionsensor:H")) {
|
|
||||||
ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
|
ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ package org.openhab.binding.ipcamera.internal;
|
|||||||
|
|
||||||
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.*;
|
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.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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
|
// If a camera does not need to poll a request as often as snapshots, it can be
|
||||||
// added here. Binding steps through the list.
|
// added here. Binding steps through the list.
|
||||||
public ArrayList<String> getLowPriorityRequests() {
|
public List<String> getLowPriorityRequests() {
|
||||||
ArrayList<String> lowPriorityRequests = new ArrayList<String>(1);
|
return List.of();
|
||||||
lowPriorityRequests.add("/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=" + username + "&pwd=" + password);
|
|
||||||
return lowPriorityRequests;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -129,4 +129,6 @@ public class IpCameraBindingConstants {
|
|||||||
public static final String CHANNEL_GOTO_PRESET = "gotoPreset";
|
public static final String CHANNEL_GOTO_PRESET = "gotoPreset";
|
||||||
public static final String CHANNEL_START_STREAM = "startStream";
|
public static final String CHANNEL_START_STREAM = "startStream";
|
||||||
public static final String CHANNEL_ENABLE_PRIVACY_MODE = "enablePrivacyMode";
|
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=\"");
|
nonce = Helper.searchString(authenticate, "nonce=\"");
|
||||||
opaque = Helper.searchString(authenticate, "opaque=\"");
|
opaque = Helper.searchString(authenticate, "opaque=\"");
|
||||||
qop = Helper.searchString(authenticate, "qop=\"");
|
qop = Helper.searchString(authenticate, "qop=\"");
|
||||||
|
|
||||||
if (!qop.isEmpty() && !realm.isEmpty()) {
|
if (!qop.isEmpty() && !realm.isEmpty()) {
|
||||||
ipCameraHandler.useDigestAuth = true;
|
ipCameraHandler.useDigestAuth = true;
|
||||||
} else {
|
} else {
|
||||||
@ -128,8 +127,10 @@ public class MyNettyAuthHandler extends ChannelDuplexHandler {
|
|||||||
|
|
||||||
String digestString = "username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\""
|
String digestString = "username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\""
|
||||||
+ requestURI + "\", cnonce=\"" + cnonce + "\", nc=" + nc + ", qop=\"" + qop + "\", response=\""
|
+ requestURI + "\", cnonce=\"" + cnonce + "\", nc=" + nc + ", qop=\"" + qop + "\", response=\""
|
||||||
+ response + "\", opaque=\"" + opaque + "\"";
|
+ response + "\"";
|
||||||
|
if (!opaque.isEmpty()) {
|
||||||
|
digestString += ", opaque=\"" + opaque + "\"";
|
||||||
|
}
|
||||||
if (reSend) {
|
if (reSend) {
|
||||||
ipCameraHandler.sendHttpRequest(httpMethod, requestURI, digestString);
|
ipCameraHandler.sendHttpRequest(httpMethod, requestURI, digestString);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -353,7 +353,7 @@ public class IpCameraGroupHandler extends BaseThingHandler {
|
|||||||
startStreamServer(true);
|
startStreamServer(true);
|
||||||
}
|
}
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
pollCameraGroupJob = pollCameraGroup.scheduleAtFixedRate(this::pollCameraGroup, 10000,
|
pollCameraGroupJob = pollCameraGroup.scheduleWithFixedDelay(this::pollCameraGroup, 10000,
|
||||||
groupConfig.getPollTime(), TimeUnit.MILLISECONDS);
|
groupConfig.getPollTime(), TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -591,8 +591,8 @@ public class IpCameraHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
logger.trace("Sending camera: {}: http://{}:{}{}", httpMethod, cameraConfig.getIp(), port,
|
logger.trace("Sending camera: {}: http://{}:{}{}", httpMethod, cameraConfig.getIp(), port,
|
||||||
httpRequestURL);
|
httpRequestURL);
|
||||||
channelTrackingMap.put(httpRequestURL, new ChannelTracking(ch, httpRequestURL));
|
|
||||||
|
|
||||||
|
openChannel(ch, httpRequestURL);
|
||||||
CommonCameraHandler commonHandler = (CommonCameraHandler) ch.pipeline().get(COMMON_HANDLER);
|
CommonCameraHandler commonHandler = (CommonCameraHandler) ch.pipeline().get(COMMON_HANDLER);
|
||||||
commonHandler.setURL(httpRequestURLFull);
|
commonHandler.setURL(httpRequestURLFull);
|
||||||
MyNettyAuthHandler authHandler = (MyNettyAuthHandler) ch.pipeline().get(AUTH_HANDLER);
|
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) {
|
void closeChannel(String url) {
|
||||||
ChannelTracking channelTracking = channelTrackingMap.get(url);
|
ChannelTracking channelTracking = channelTrackingMap.get(url);
|
||||||
if (channelTracking != null) {
|
if (channelTracking != null) {
|
||||||
@ -1412,9 +1421,22 @@ public class IpCameraHandler extends BaseThingHandler {
|
|||||||
localFuture.cancel(false);
|
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")) {
|
if (cameraConfig.getGifPreroll() > 0 || cameraConfig.getUpdateImageWhen().contains("1")) {
|
||||||
snapshotPolling = true;
|
snapshotPolling = true;
|
||||||
snapshotJob = threadPool.scheduleAtFixedRate(this::snapshotRunnable, 1000, cameraConfig.getPollTime(),
|
snapshotJob = threadPool.scheduleWithFixedDelay(this::snapshotRunnable, 1000, cameraConfig.getPollTime(),
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1537,11 +1559,11 @@ public class IpCameraHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
if (streamingSnapshotMjpeg || streamingAutoFps) {
|
if (streamingSnapshotMjpeg || streamingAutoFps) {
|
||||||
snapshotPolling = true;
|
snapshotPolling = true;
|
||||||
snapshotJob = threadPool.scheduleAtFixedRate(this::snapshotRunnable, 200, cameraConfig.getPollTime(),
|
snapshotJob = threadPool.scheduleWithFixedDelay(this::snapshotRunnable, 200, cameraConfig.getPollTime(),
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
} else if (cameraConfig.getUpdateImageWhen().contains("4")) { // During Motion Alarms
|
} else if (cameraConfig.getUpdateImageWhen().contains("4")) { // During Motion Alarms
|
||||||
snapshotPolling = true;
|
snapshotPolling = true;
|
||||||
snapshotJob = threadPool.scheduleAtFixedRate(this::snapshotRunnable, 200, cameraConfig.getPollTime(),
|
snapshotJob = threadPool.scheduleWithFixedDelay(this::snapshotRunnable, 200, cameraConfig.getPollTime(),
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1610,6 +1632,10 @@ public class IpCameraHandler extends BaseThingHandler {
|
|||||||
sendHttpGET("/bha-api/monitor.cgi?ring=doorbell,motionsensor");
|
sendHttpGET("/bha-api/monitor.cgi?ring=doorbell,motionsensor");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FOSCAM_THING:
|
||||||
|
sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=" + cameraConfig.getUser() + "&pwd="
|
||||||
|
+ cameraConfig.getPassword());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Ffmpeg localHLS = ffmpegHLS;
|
Ffmpeg localHLS = ffmpegHLS;
|
||||||
if (localHLS != null) {
|
if (localHLS != null) {
|
||||||
@ -1747,6 +1773,7 @@ public class IpCameraHandler extends BaseThingHandler {
|
|||||||
Ffmpeg localFfmpeg = ffmpegHLS;
|
Ffmpeg localFfmpeg = ffmpegHLS;
|
||||||
if (localFfmpeg != null) {
|
if (localFfmpeg != null) {
|
||||||
localFfmpeg.stopConverting();
|
localFfmpeg.stopConverting();
|
||||||
|
localFfmpeg = null;
|
||||||
}
|
}
|
||||||
localFfmpeg = ffmpegRecord;
|
localFfmpeg = ffmpegRecord;
|
||||||
if (localFfmpeg != null) {
|
if (localFfmpeg != null) {
|
||||||
|
|||||||
@ -124,9 +124,9 @@ public class OnvifDiscovery {
|
|||||||
|
|
||||||
void processCameraReplys() {
|
void processCameraReplys() {
|
||||||
for (DatagramPacket packet : listOfReplys) {
|
for (DatagramPacket packet : listOfReplys) {
|
||||||
logger.trace("Device replied to discovery with:{}", packet.toString());
|
|
||||||
String xml = packet.content().toString(CharsetUtil.UTF_8);
|
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("")) {
|
if (!xAddr.equals("")) {
|
||||||
searchReply(xAddr, xml);
|
searchReply(xAddr, xml);
|
||||||
} else if (xml.contains("onvif")) {
|
} else if (xml.contains("onvif")) {
|
||||||
|
|||||||
@ -936,6 +936,11 @@
|
|||||||
<channel id="imageUrl" typeId="imageUrl"/>
|
<channel id="imageUrl" typeId="imageUrl"/>
|
||||||
<channel id="hlsUrl" typeId="hlsUrl"/>
|
<channel id="hlsUrl" typeId="hlsUrl"/>
|
||||||
<channel id="enablePrivacyMode" typeId="enablePrivacyMode"/>
|
<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>
|
</channels>
|
||||||
<config-description>
|
<config-description>
|
||||||
|
|
||||||
@ -2542,6 +2547,22 @@
|
|||||||
<state readOnly="true"/>
|
<state readOnly="true"/>
|
||||||
</channel-type>
|
</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">
|
<channel-type id="parkingAlarm" advanced="true">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Parking Alarm</label>
|
<label>Parking Alarm</label>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user