Skip to content

Commit fd4284a

Browse files
mesetkaSkinahlsiepel
authored
[ipcamera] Add new channels for Dahua API-based doorphones (openhab#13313)
* Made all changes requested by codeowner, added additional useful channels, fixing changes before going to channels organizing into groups and dynamic channels deletion. Signed-off-by: mesetka <[email protected]> Co-authored-by: Matthew Skinner <[email protected]> Co-authored-by: Leo Siepel <[email protected]>
1 parent ec99892 commit fd4284a

File tree

6 files changed

+377
-78
lines changed

6 files changed

+377
-78
lines changed

bundles/org.openhab.binding.ipcamera/README.md

+76-68
Large diffs are not rendered by default.

bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/DahuaHandler.java

+163-9
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,41 @@
1212
*/
1313
package org.openhab.binding.ipcamera.internal;
1414

15-
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.*;
15+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ACCEPTED_CARD_NUMBER;
16+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ACTIVATE_ALARM_OUTPUT;
17+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ACTIVATE_ALARM_OUTPUT2;
18+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_AUTO_LED;
19+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_AUTO_WHITE_LED;
20+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_CAR_ALARM;
21+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_DOOR_CONTACT;
22+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_DOOR_UNLOCK;
23+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ENABLE_AUDIO_ALARM;
24+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ENABLE_LED;
25+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ENABLE_LINE_CROSSING_ALARM;
26+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ENABLE_MOTION_ALARM;
27+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ENABLE_PRIVACY_MODE;
28+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_EXIT_BUTTON;
29+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_EXIT_BUTTON_ENABLED;
30+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_EXTERNAL_ALARM_INPUT;
31+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_EXTERNAL_ALARM_INPUT2;
32+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_FACE_DETECTED;
33+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_FIELD_DETECTION_ALARM;
34+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_HUMAN_ALARM;
35+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ITEM_LEFT;
36+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_ITEM_TAKEN;
37+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_LAST_EVENT_DATA;
38+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_LINE_CROSSING_ALARM;
39+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_MAGNETIC_LOCK_WARNING;
40+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_MOTION_ALARM;
41+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_MOTION_DETECTION_LEVEL;
42+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_PARKING_ALARM;
43+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_SCENE_CHANGE_ALARM;
44+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_TEXT_OVERLAY;
45+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_THRESHOLD_AUDIO_ALARM;
46+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_TOO_BLURRY_ALARM;
47+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_TOO_DARK_ALARM;
48+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_UNACCEPTED_CARD_NUMBER;
49+
import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.CHANNEL_WHITE_LED;
1650

1751
import java.util.List;
1852
import java.util.regex.Pattern;
@@ -23,6 +57,7 @@
2357
import org.openhab.binding.ipcamera.internal.onvif.OnvifConnection.RequestType;
2458
import org.openhab.core.library.types.DecimalType;
2559
import org.openhab.core.library.types.OnOffType;
60+
import org.openhab.core.library.types.OpenClosedType;
2661
import org.openhab.core.library.types.PercentType;
2762
import org.openhab.core.library.types.StringType;
2863
import org.openhab.core.thing.ChannelUID;
@@ -172,18 +207,87 @@ private void processEvent(String content) {
172207
ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.OFF);
173208
}
174209
break;
210+
case "AccessControl":
211+
if ("Pulse".equals(action)) {
212+
if (content.contains("\"Method\" : 1")) {
213+
if (content.contains("\"ErrorCode\" : 0")) {
214+
startIndex = content.indexOf("CardNo", startIndex) + 11;
215+
if (startIndex > 0) {
216+
endIndex = content.indexOf(",", startIndex) - 1;
217+
String cardNo = content.substring(startIndex, endIndex);
218+
ipCameraHandler.setChannelState(CHANNEL_ACCEPTED_CARD_NUMBER, new StringType(cardNo));
219+
ipCameraHandler.setChannelState(CHANNEL_DOOR_UNLOCK, OnOffType.ON);
220+
}
221+
}
222+
} else if (content.contains("\"Method\" : 5")) {
223+
ipCameraHandler.setChannelState(CHANNEL_DOOR_UNLOCK, OnOffType.ON);
224+
ipCameraHandler.logger.debug("Door opened from button");
225+
} else if (content.contains("\"Method\" : 4")) {
226+
ipCameraHandler.setChannelState(CHANNEL_DOOR_UNLOCK, OnOffType.ON);
227+
ipCameraHandler.logger.debug("Door opened remotely");
228+
}
229+
} else {
230+
ipCameraHandler.logger.debug("Unrecognised Access control Dahua event, content={}", content);
231+
}
232+
break;
233+
case "DoorCard":
234+
if ("Pulse".equals(action)) {
235+
if (content.contains("\"Number\"")) {
236+
startIndex = content.indexOf("Number", startIndex) + 11;
237+
if (startIndex > 0) {
238+
endIndex = content.indexOf(",", startIndex) - 1;
239+
String cardNo = content.substring(startIndex, endIndex);
240+
ipCameraHandler.setChannelState(CHANNEL_UNACCEPTED_CARD_NUMBER, new StringType(cardNo));
241+
}
242+
}
243+
} else {
244+
ipCameraHandler.logger.debug("Unrecognised Access control Dahua event, content={}", content);
245+
}
246+
break;
247+
case "ProfileAlarmTransmit":
248+
if ("Start".equals(action)) {
249+
if (content.contains("DoorMagnetism")) {
250+
ipCameraHandler.setChannelState(CHANNEL_MAGNETIC_LOCK_WARNING, OnOffType.ON);
251+
}
252+
} else if ("Stop".equals(action)) {
253+
if (content.contains("DoorMagnetism")) {
254+
ipCameraHandler.setChannelState(CHANNEL_MAGNETIC_LOCK_WARNING, OnOffType.OFF);
255+
}
256+
} else {
257+
ipCameraHandler.logger.debug("Unrecognised Alarm Dahua event, content={}", content);
258+
}
259+
break;
260+
case "DoorStatus":
261+
if ("Pulse".equals(action)) {
262+
if (content.contains("\"Relay\" : true")) {
263+
ipCameraHandler.setChannelState(CHANNEL_DOOR_UNLOCK, OnOffType.OFF);
264+
} else if (content.contains("\"Status\" : \"Close\"")) {
265+
ipCameraHandler.setChannelState(CHANNEL_DOOR_CONTACT, OpenClosedType.CLOSED);
266+
} else if (content.contains("\"Status\" : \"Open\"")) {
267+
ipCameraHandler.setChannelState(CHANNEL_DOOR_CONTACT, OpenClosedType.OPEN);
268+
} else {
269+
ipCameraHandler.logger.debug("Unrecognised Door status Dahua event, content={}", content);
270+
}
271+
}
272+
break;
175273
case "AlarmLocal":
176274
if ("Start".equals(action)) {
177275
if (content.contains("index=0")) {
178276
ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.ON);
277+
} else if (content.contains("index=3")) {
278+
ipCameraHandler.setChannelState(CHANNEL_EXIT_BUTTON, OnOffType.ON);
179279
} else {
180280
ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.ON);
281+
ipCameraHandler.logger.trace("External alarm Dahua event, content={}", content);
181282
}
182283
} else if ("Stop".equals(action)) {
183284
if (content.contains("index=0")) {
184285
ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.OFF);
286+
} else if (content.contains("index=3")) {
287+
ipCameraHandler.setChannelState(CHANNEL_EXIT_BUTTON, OnOffType.OFF);
185288
} else {
186289
ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.OFF);
290+
ipCameraHandler.logger.trace("External alarm Dahua event, content={}", content);
187291
}
188292
}
189293
break;
@@ -209,6 +313,7 @@ private void processEvent(String content) {
209313
case "LeFunctionStatusSync":
210314
case "RecordDelete":
211315
case "InterVideoAccess":
316+
case "SIPRegisterResult":
212317
break;
213318
default:
214319
ipCameraHandler.logger.debug("Unrecognised Dahua event, Code={}, action={}", code, action);
@@ -223,6 +328,12 @@ private void processSettings(String content) {
223328
ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.OFF);
224329
}
225330

331+
// Handle MotionDetectLevel alarm
332+
if (content.contains("table.MotionDetect[0].Level=")) {
333+
String value = ipCameraHandler.returnValueFromString(content, "table.MotionDetect[0].Level=");
334+
ipCameraHandler.setChannelState(CHANNEL_MOTION_DETECTION_LEVEL, DecimalType.valueOf(value));
335+
}
336+
226337
// determine if the audio alarm is turned on or off.
227338
if (content.contains("table.AudioDetect[" + nvrChannelAdjusted + "].MutationDetect=true")) {
228339
ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
@@ -249,6 +360,13 @@ private void processSettings(String content) {
249360
} else if (content.contains("table.LeLensMask[" + nvrChannelAdjusted + "].Enable=false")) {
250361
ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF);
251362
}
363+
364+
// determine if exit button is enabled
365+
if (content.contains("table.AccessControlGeneral.ButtonExitEnable=true")) {
366+
ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.ON);
367+
} else if (content.contains("table.AccessControlGeneral.ButtonExitEnable=false")) {
368+
ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF);
369+
}
252370
}
253371

254372
// This handles the incoming http replies back from the camera.
@@ -303,6 +421,14 @@ public void handleCommand(ChannelUID channelUID, Command command) {
303421
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=Lighting_V2["
304422
+ nvrChannelAdjusted + "][0][1].Mode");
305423
return;
424+
case CHANNEL_MOTION_DETECTION_LEVEL:
425+
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=MotionDetect["
426+
+ nvrChannelAdjusted + "]");
427+
return;
428+
case CHANNEL_EXIT_BUTTON_ENABLED:
429+
ipCameraHandler
430+
.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=AccessControlGeneral");
431+
return;
306432
}
307433
return;
308434
} // end of "REFRESH"
@@ -369,14 +495,14 @@ public void handleCommand(ChannelUID channelUID, Command command) {
369495
}
370496
return;
371497
case CHANNEL_THRESHOLD_AUDIO_ALARM:
372-
int threshold = Math.round(Float.valueOf(command.toString()));
373-
374-
if (threshold == 0) {
375-
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AudioDetect["
376-
+ nvrChannelAdjusted + "].MutationThreold=1");
377-
} else {
378-
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AudioDetect["
379-
+ nvrChannelAdjusted + "].MutationThreold=" + threshold);
498+
if (command instanceof PercentType percentCommand) {
499+
if (PercentType.ZERO.equals(command)) {
500+
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AudioDetect["
501+
+ nvrChannelAdjusted + "].MutationThreold=1");
502+
} else {
503+
ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AudioDetect["
504+
+ nvrChannelAdjusted + "].MutationThreold=" + percentCommand.intValue());
505+
}
380506
}
381507
return;
382508
case CHANNEL_ENABLE_AUDIO_ALARM:
@@ -406,6 +532,19 @@ public void handleCommand(ChannelUID channelUID, Command command) {
406532
+ nvrChannelAdjusted + "].Enable=false");
407533
}
408534
return;
535+
case CHANNEL_MOTION_DETECTION_LEVEL:
536+
if (command instanceof DecimalType decimalCommand) {
537+
if (DecimalType.ZERO.equals(command)) {
538+
ipCameraHandler.sendHttpGET(
539+
"/cgi-bin/configManager.cgi?action=setConfig&MotionDetect[0].Enable=false&MotionDetect[0].Level="
540+
+ decimalCommand.intValue());
541+
} else {
542+
ipCameraHandler.sendHttpGET(
543+
"/cgi-bin/configManager.cgi?action=setConfig&MotionDetect[0].Enable=true&MotionDetect[0].EventHandler.Dejitter=1&MotionDetect[0].Level="
544+
+ decimalCommand.intValue());
545+
}
546+
}
547+
return;
409548
case CHANNEL_ACTIVATE_ALARM_OUTPUT:
410549
if (OnOffType.ON.equals(command)) {
411550
ipCameraHandler.sendHttpGET(
@@ -431,6 +570,21 @@ public void handleCommand(ChannelUID channelUID, Command command) {
431570
+ nvrChannelAdjusted + "].Enable=true");
432571
}
433572
return;
573+
case CHANNEL_DOOR_UNLOCK:
574+
if (OnOffType.ON.equals(command)) {
575+
ipCameraHandler
576+
.sendHttpGET("/cgi-bin/accessControl.cgi?action=openDoor&channel=1&UserID=101&Type=Remote");
577+
}
578+
return;
579+
case CHANNEL_EXIT_BUTTON_ENABLED:
580+
if (OnOffType.ON.equals(command)) {
581+
ipCameraHandler.sendHttpGET(
582+
"/cgi-bin/configManager.cgi?action=setConfig&AccessControlGeneral.ButtonExitEnable=true");
583+
} else if (OnOffType.OFF.equals(command)) {
584+
ipCameraHandler.sendHttpGET(
585+
"/cgi-bin/configManager.cgi?action=setConfig&AccessControlGeneral.ButtonExitEnable=false");
586+
}
587+
return;
434588
}
435589
}
436590

bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/IpCameraBindingConstants.java

+8
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,12 @@ public enum FFmpegFormat {
150150
public static final String CHANNEL_ENABLE_PUSH = "enablePush";
151151
public static final String CHANNEL_ENABLE_RECORDINGS = "enableRecordings";
152152
public static final String CHANNEL_AUTO_TRACKING = "autoTracking";
153+
public static final String CHANNEL_ACCEPTED_CARD_NUMBER = "acceptedCardNumber";
154+
public static final String CHANNEL_UNACCEPTED_CARD_NUMBER = "unacceptedCardNumber";
155+
public static final String CHANNEL_DOOR_UNLOCK = "doorUnlock";
156+
public static final String CHANNEL_DOOR_CONTACT = "doorContact";
157+
public static final String CHANNEL_EXIT_BUTTON = "exitButton";
158+
public static final String CHANNEL_MOTION_DETECTION_LEVEL = "motionDetectionLevel";
159+
public static final String CHANNEL_EXIT_BUTTON_ENABLED = "exitButtonEnabled";
160+
public static final String CHANNEL_MAGNETIC_LOCK_WARNING = "magneticLockWarning";
153161
}

0 commit comments

Comments
 (0)