]> git.basschouten.com Git - openhab-addons.git/blob
816233f2619a20ef3087c3e2400d8af145964e52
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.ipcamera.internal;
14
15 import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.*;
16
17 import java.util.List;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.ipcamera.internal.handler.IpCameraHandler;
22 import org.openhab.core.library.types.DecimalType;
23 import org.openhab.core.library.types.OnOffType;
24 import org.openhab.core.library.types.PercentType;
25 import org.openhab.core.thing.ChannelUID;
26 import org.openhab.core.types.Command;
27 import org.openhab.core.types.RefreshType;
28 import org.openhab.core.types.UnDefType;
29
30 import io.netty.channel.ChannelDuplexHandler;
31 import io.netty.channel.ChannelHandlerContext;
32 import io.netty.util.ReferenceCountUtil;
33
34 /**
35  * The {@link DahuaHandler} is responsible for handling commands, which are
36  * sent to one of the channels.
37  *
38  * @author Matthew Skinner - Initial contribution
39  */
40
41 @NonNullByDefault
42 public class DahuaHandler extends ChannelDuplexHandler {
43     private IpCameraHandler ipCameraHandler;
44     private int nvrChannel;
45
46     public DahuaHandler(IpCameraHandler handler, int nvrChannel) {
47         ipCameraHandler = handler;
48         this.nvrChannel = nvrChannel;
49     }
50
51     private void processEvent(String content) {
52         int startIndex = content.indexOf("Code=", 12) + 5;// skip --myboundary and Code=
53         int endIndex = content.indexOf(";", startIndex + 1);
54         if (startIndex == -1 || endIndex == -1) {
55             ipCameraHandler.logger.debug("Code= not found in Dahua event. Content was:{}", content);
56             return;
57         }
58         String code = content.substring(startIndex, endIndex);
59         startIndex = endIndex + 8;// skip ;action=
60         endIndex = content.indexOf(";", startIndex);
61         if (startIndex == -1 || endIndex == -1) {
62             ipCameraHandler.logger.debug(";action= not found in Dahua event. Content was:{}", content);
63             return;
64         }
65         String action = content.substring(startIndex, endIndex);
66         switch (code) {
67             case "VideoMotion":
68                 if ("Start".equals(action)) {
69                     ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
70                 } else if ("Stop".equals(action)) {
71                     ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
72                 }
73                 break;
74             case "TakenAwayDetection":
75                 if ("Start".equals(action)) {
76                     ipCameraHandler.motionDetected(CHANNEL_ITEM_TAKEN);
77                 } else if ("Stop".equals(action)) {
78                     ipCameraHandler.noMotionDetected(CHANNEL_ITEM_TAKEN);
79                 }
80                 break;
81             case "LeftDetection":
82                 if ("Start".equals(action)) {
83                     ipCameraHandler.motionDetected(CHANNEL_ITEM_LEFT);
84                 } else if ("Stop".equals(action)) {
85                     ipCameraHandler.noMotionDetected(CHANNEL_ITEM_LEFT);
86                 }
87                 break;
88             case "SmartMotionVehicle":
89                 if ("Start".equals(action)) {
90                     ipCameraHandler.motionDetected(CHANNEL_CAR_ALARM);
91                 } else if ("Stop".equals(action)) {
92                     ipCameraHandler.noMotionDetected(CHANNEL_CAR_ALARM);
93                 }
94                 break;
95             case "SmartMotionHuman":
96                 if ("Start".equals(action)) {
97                     ipCameraHandler.motionDetected(CHANNEL_HUMAN_ALARM);
98                 } else if ("Stop".equals(action)) {
99                     ipCameraHandler.noMotionDetected(CHANNEL_HUMAN_ALARM);
100                 }
101                 break;
102             case "CrossLineDetection":
103                 if ("Start".equals(action)) {
104                     ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM);
105                 } else if ("Stop".equals(action)) {
106                     ipCameraHandler.noMotionDetected(CHANNEL_LINE_CROSSING_ALARM);
107                 }
108                 break;
109             case "AudioMutation":
110                 if ("Start".equals(action)) {
111                     ipCameraHandler.audioDetected();
112                 } else if ("Stop".equals(action)) {
113                     ipCameraHandler.noAudioDetected();
114                 }
115                 break;
116             case "FaceDetection":
117                 if ("Start".equals(action)) {
118                     ipCameraHandler.motionDetected(CHANNEL_FACE_DETECTED);
119                 } else if ("Stop".equals(action)) {
120                     ipCameraHandler.noMotionDetected(CHANNEL_FACE_DETECTED);
121                 }
122                 break;
123             case "ParkingDetection":
124                 if ("Start".equals(action)) {
125                     ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.ON);
126                 } else if ("Stop".equals(action)) {
127                     ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.OFF);
128                 }
129                 break;
130             case "CrossRegionDetection":
131                 if ("Start".equals(action)) {
132                     ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM);
133                 } else if ("Stop".equals(action)) {
134                     ipCameraHandler.noMotionDetected(CHANNEL_FIELD_DETECTION_ALARM);
135                 }
136                 break;
137             case "VideoLoss":
138             case "VideoBlind":
139                 if ("Start".equals(action)) {
140                     ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.ON);
141                 } else if ("Stop".equals(action)) {
142                     ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.OFF);
143                 }
144                 break;
145             case "VideoAbnormalDetection":
146                 if ("Start".equals(action)) {
147                     ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.ON);
148                 } else if ("Stop".equals(action)) {
149                     ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.OFF);
150                 }
151                 break;
152             case "VideoUnFocus":
153                 if ("Start".equals(action)) {
154                     ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.ON);
155                 } else if ("Stop".equals(action)) {
156                     ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.OFF);
157                 }
158                 break;
159             case "AlarmLocal":
160                 if ("Start".equals(action)) {
161                     if (content.contains("index=0")) {
162                         ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.ON);
163                     } else {
164                         ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.ON);
165                     }
166                 } else if ("Stop".equals(action)) {
167                     if (content.contains("index=0")) {
168                         ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.OFF);
169                     } else {
170                         ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.OFF);
171                     }
172                 }
173                 break;
174             case "LensMaskOpen":
175                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.ON);
176                 break;
177             case "LensMaskClose":
178                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF);
179                 break;
180             // Skip these so they are not logged.
181             case "TimeChange":
182             case "IntelliFrame":
183             case "NTPAdjustTime":
184             case "StorageChange":
185             case "Reboot":
186             case "NewFile":
187             case "VideoMotionInfo":
188             case "RtspSessionDisconnect":
189             case "LeFunctionStatusSync":
190             case "RecordDelete":
191                 break;
192             default:
193                 ipCameraHandler.logger.debug("Unrecognised Dahua event, Code={}, action={}", code, action);
194         }
195     }
196
197     // This handles the incoming http replies back from the camera.
198     @Override
199     public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception {
200         if (msg == null || ctx == null) {
201             return;
202         }
203         try {
204             String content = msg.toString();
205             if (content.startsWith("--myboundary")) {
206                 processEvent(content);
207                 return;
208             }
209             ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content);
210             // determine if the motion detection is turned on or off.
211             if (content.contains("table.MotionDetect[0].Enable=true")) {
212                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.ON);
213             } else if (content.contains("table.MotionDetect[" + nvrChannel + "].Enable=false")) {
214                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.OFF);
215             }
216
217             // determine if the audio alarm is turned on or off.
218             if (content.contains("table.AudioDetect[0].MutationDetect=true")) {
219                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
220             } else if (content.contains("table.AudioDetect[0].MutationDetect=false")) {
221                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.OFF);
222             }
223
224             // Handle AudioMutationThreshold alarm
225             if (content.contains("table.AudioDetect[0].MutationThreold=")) {
226                 String value = ipCameraHandler.returnValueFromString(content, "table.AudioDetect[0].MutationThreold=");
227                 ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.valueOf(value));
228             }
229
230             // CrossLineDetection alarm on/off
231             if (content.contains("table.VideoAnalyseRule[0][1].Enable=true")) {
232                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.ON);
233             } else if (content.contains("table.VideoAnalyseRule[0][1].Enable=false")) {
234                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.OFF);
235             }
236             // Privacy Mode on/off
237             if (content.contains("table.LeLensMask[0].Enable=true")) {
238                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.ON);
239             } else if (content.contains("table.LeLensMask[0].Enable=false")) {
240                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF);
241             }
242         } finally {
243             ReferenceCountUtil.release(msg);
244         }
245     }
246
247     // This handles the commands that come from the openHAB event bus.
248     public void handleCommand(ChannelUID channelUID, Command command) {
249         if (command instanceof RefreshType) {
250             switch (channelUID.getId()) {
251                 case CHANNEL_ENABLE_AUDIO_ALARM:
252                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=AudioDetect[0]");
253                     return;
254                 case CHANNEL_ENABLE_LINE_CROSSING_ALARM:
255                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=VideoAnalyseRule");
256                     return;
257                 case CHANNEL_ENABLE_MOTION_ALARM:
258                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=MotionDetect[0]");
259                     return;
260                 case CHANNEL_ENABLE_PRIVACY_MODE:
261                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=LeLensMask[0]");
262                     return;
263             }
264             return;
265         } // end of "REFRESH"
266         switch (channelUID.getId()) {
267             case CHANNEL_TEXT_OVERLAY:
268                 String text = Helper.encodeSpecialChars(command.toString());
269                 if (text.isEmpty()) {
270                     ipCameraHandler.sendHttpGET(
271                             "/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].EncodeBlend=false");
272                 } else {
273                     ipCameraHandler.sendHttpGET(
274                             "/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].EncodeBlend=true&VideoWidget[0].CustomTitle[1].Text="
275                                     + text);
276                 }
277                 return;
278             case CHANNEL_ENABLE_LED:
279                 ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF);
280                 if (DecimalType.ZERO.equals(command) || OnOffType.OFF.equals(command)) {
281                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Off");
282                 } else if (OnOffType.ON.equals(command)) {
283                     ipCameraHandler
284                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Manual");
285                 } else {
286                     ipCameraHandler.sendHttpGET(
287                             "/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Manual&Lighting[0][0].MiddleLight[0].Light="
288                                     + command.toString());
289                 }
290                 return;
291             case CHANNEL_AUTO_LED:
292                 if (OnOffType.ON.equals(command)) {
293                     ipCameraHandler.setChannelState(CHANNEL_ENABLE_LED, UnDefType.UNDEF);
294                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Auto");
295                 }
296                 return;
297             case CHANNEL_THRESHOLD_AUDIO_ALARM:
298                 int threshold = Math.round(Float.valueOf(command.toString()));
299
300                 if (threshold == 0) {
301                     ipCameraHandler.sendHttpGET(
302                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationThreold=1");
303                 } else {
304                     ipCameraHandler.sendHttpGET(
305                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationThreold=" + threshold);
306                 }
307                 return;
308             case CHANNEL_ENABLE_AUDIO_ALARM:
309                 if (OnOffType.ON.equals(command)) {
310                     ipCameraHandler.sendHttpGET(
311                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationDetect=true&AudioDetect[0].EventHandler.Dejitter=1");
312                 } else {
313                     ipCameraHandler.sendHttpGET(
314                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationDetect=false");
315                 }
316                 return;
317             case CHANNEL_ENABLE_LINE_CROSSING_ALARM:
318                 if (OnOffType.ON.equals(command)) {
319                     ipCameraHandler.sendHttpGET(
320                             "/cgi-bin/configManager.cgi?action=setConfig&VideoAnalyseRule[0][1].Enable=true");
321                 } else {
322                     ipCameraHandler.sendHttpGET(
323                             "/cgi-bin/configManager.cgi?action=setConfig&VideoAnalyseRule[0][1].Enable=false");
324                 }
325                 return;
326             case CHANNEL_ENABLE_MOTION_ALARM:
327                 if (OnOffType.ON.equals(command)) {
328                     ipCameraHandler.sendHttpGET(
329                             "/cgi-bin/configManager.cgi?action=setConfig&MotionDetect[0].Enable=true&MotionDetect[0].EventHandler.Dejitter=1");
330                 } else {
331                     ipCameraHandler
332                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&MotionDetect[0].Enable=false");
333                 }
334                 return;
335             case CHANNEL_ACTIVATE_ALARM_OUTPUT:
336                 if (OnOffType.ON.equals(command)) {
337                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[0].Mode=1");
338                 } else {
339                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[0].Mode=0");
340                 }
341                 return;
342             case CHANNEL_ACTIVATE_ALARM_OUTPUT2:
343                 if (OnOffType.ON.equals(command)) {
344                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[1].Mode=1");
345                 } else {
346                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[1].Mode=0");
347                 }
348                 return;
349             case CHANNEL_ENABLE_PRIVACY_MODE:
350                 if (OnOffType.OFF.equals(command)) {
351                     ipCameraHandler
352                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&LeLensMask[0].Enable=false");
353                 } else if (OnOffType.ON.equals(command)) {
354                     ipCameraHandler
355                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&LeLensMask[0].Enable=true");
356                 }
357                 return;
358         }
359     }
360
361     // If a camera does not need to poll a request as often as snapshots, it can be
362     // added here. Binding steps through the list.
363     public List<String> getLowPriorityRequests() {
364         return List.of();
365     }
366 }