]> git.basschouten.com Git - openhab-addons.git/blob
65234b506364afa679eecf1fb63b4608702bb243
[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
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 (action.equals("Start")) {
69                     ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
70                 } else if (action.equals("Stop")) {
71                     ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
72                 }
73                 break;
74             case "TakenAwayDetection":
75                 if (action.equals("Start")) {
76                     ipCameraHandler.motionDetected(CHANNEL_ITEM_TAKEN);
77                 } else if (action.equals("Stop")) {
78                     ipCameraHandler.noMotionDetected(CHANNEL_ITEM_TAKEN);
79                 }
80                 break;
81             case "LeftDetection":
82                 if (action.equals("Start")) {
83                     ipCameraHandler.motionDetected(CHANNEL_ITEM_LEFT);
84                 } else if (action.equals("Stop")) {
85                     ipCameraHandler.noMotionDetected(CHANNEL_ITEM_LEFT);
86                 }
87                 break;
88             case "SmartMotionVehicle":
89                 if (action.equals("Start")) {
90                     ipCameraHandler.motionDetected(CHANNEL_CAR_ALARM);
91                 } else if (action.equals("Stop")) {
92                     ipCameraHandler.noMotionDetected(CHANNEL_CAR_ALARM);
93                 }
94                 break;
95             case "SmartMotionHuman":
96                 if (action.equals("Start")) {
97                     ipCameraHandler.motionDetected(CHANNEL_HUMAN_ALARM);
98                 } else if (action.equals("Stop")) {
99                     ipCameraHandler.noMotionDetected(CHANNEL_HUMAN_ALARM);
100                 }
101                 break;
102             case "CrossLineDetection":
103                 if (action.equals("Start")) {
104                     ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM);
105                 } else if (action.equals("Stop")) {
106                     ipCameraHandler.noMotionDetected(CHANNEL_LINE_CROSSING_ALARM);
107                 }
108                 break;
109             case "AudioMutation":
110                 if (action.equals("Start")) {
111                     ipCameraHandler.audioDetected();
112                 } else if (action.equals("Stop")) {
113                     ipCameraHandler.noAudioDetected();
114                 }
115                 break;
116             case "FaceDetection":
117                 if (action.equals("Start")) {
118                     ipCameraHandler.motionDetected(CHANNEL_FACE_DETECTED);
119                 } else if (action.equals("Stop")) {
120                     ipCameraHandler.noMotionDetected(CHANNEL_FACE_DETECTED);
121                 }
122                 break;
123             case "ParkingDetection":
124                 if (action.equals("Start")) {
125                     ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.ON);
126                 } else if (action.equals("Stop")) {
127                     ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.OFF);
128                 }
129                 break;
130             case "CrossRegionDetection":
131                 if (action.equals("Start")) {
132                     ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM);
133                 } else if (action.equals("Stop")) {
134                     ipCameraHandler.noMotionDetected(CHANNEL_FIELD_DETECTION_ALARM);
135                 }
136                 break;
137             case "VideoLoss":
138             case "VideoBlind":
139                 if (action.equals("Start")) {
140                     ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.ON);
141                 } else if (action.equals("Stop")) {
142                     ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.OFF);
143                 }
144                 break;
145             case "VideoAbnormalDetection":
146                 if (action.equals("Start")) {
147                     ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.ON);
148                 } else if (action.equals("Stop")) {
149                     ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.OFF);
150                 }
151                 break;
152             case "VideoUnFocus":
153                 if (action.equals("Start")) {
154                     ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.ON);
155                 } else if (action.equals("Stop")) {
156                     ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.OFF);
157                 }
158                 break;
159             case "AlarmLocal":
160                 if (action.equals("Start")) {
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 (action.equals("Stop")) {
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             case "TimeChange":
181             case "NTPAdjustTime":
182             case "StorageChange":
183             case "Reboot":
184             case "NewFile":
185             case "VideoMotionInfo":
186             case "RtspSessionDisconnect":
187             case "LeFunctionStatusSync":
188             case "RecordDelete":
189                 break;
190             default:
191                 ipCameraHandler.logger.debug("Unrecognised Dahua event, Code={}, action={}", code, action);
192         }
193     }
194
195     // This handles the incoming http replies back from the camera.
196     @Override
197     public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception {
198         if (msg == null || ctx == null) {
199             return;
200         }
201         try {
202             String content = msg.toString();
203             if (content.startsWith("--myboundary")) {
204                 processEvent(content);
205                 return;
206             }
207             ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content);
208             // determine if the motion detection is turned on or off.
209             if (content.contains("table.MotionDetect[0].Enable=true")) {
210                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.ON);
211             } else if (content.contains("table.MotionDetect[" + nvrChannel + "].Enable=false")) {
212                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.OFF);
213             }
214
215             // determine if the audio alarm is turned on or off.
216             if (content.contains("table.AudioDetect[0].MutationDetect=true")) {
217                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
218             } else if (content.contains("table.AudioDetect[0].MutationDetect=false")) {
219                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.OFF);
220             }
221
222             // Handle AudioMutationThreshold alarm
223             if (content.contains("table.AudioDetect[0].MutationThreold=")) {
224                 String value = ipCameraHandler.returnValueFromString(content, "table.AudioDetect[0].MutationThreold=");
225                 ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.valueOf(value));
226             }
227
228             // CrossLineDetection alarm on/off
229             if (content.contains("table.VideoAnalyseRule[0][1].Enable=true")) {
230                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.ON);
231             } else if (content.contains("table.VideoAnalyseRule[0][1].Enable=false")) {
232                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_LINE_CROSSING_ALARM, OnOffType.OFF);
233             }
234             // Privacy Mode on/off
235             if (content.contains("table.LeLensMask[0].Enable=true")) {
236                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.ON);
237             } else if (content.contains("table.LeLensMask[0].Enable=false")) {
238                 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PRIVACY_MODE, OnOffType.OFF);
239             }
240         } finally {
241             ReferenceCountUtil.release(msg);
242         }
243     }
244
245     // This handles the commands that come from the openHAB event bus.
246     public void handleCommand(ChannelUID channelUID, Command command) {
247         if (command instanceof RefreshType) {
248             switch (channelUID.getId()) {
249                 case CHANNEL_ENABLE_AUDIO_ALARM:
250                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=AudioDetect[0]");
251                     return;
252                 case CHANNEL_ENABLE_LINE_CROSSING_ALARM:
253                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=VideoAnalyseRule");
254                     return;
255                 case CHANNEL_ENABLE_MOTION_ALARM:
256                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=MotionDetect[0]");
257                     return;
258                 case CHANNEL_ENABLE_PRIVACY_MODE:
259                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=getConfig&name=LeLensMask[0]");
260                     return;
261             }
262             return;
263         } // end of "REFRESH"
264         switch (channelUID.getId()) {
265             case CHANNEL_TEXT_OVERLAY:
266                 String text = Helper.encodeSpecialChars(command.toString());
267                 if (text.isEmpty()) {
268                     ipCameraHandler.sendHttpGET(
269                             "/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].EncodeBlend=false");
270                 } else {
271                     ipCameraHandler.sendHttpGET(
272                             "/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].EncodeBlend=true&VideoWidget[0].CustomTitle[1].Text="
273                                     + text);
274                 }
275                 return;
276             case CHANNEL_ENABLE_LED:
277                 ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF);
278                 if (DecimalType.ZERO.equals(command) || OnOffType.OFF.equals(command)) {
279                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Off");
280                 } else if (OnOffType.ON.equals(command)) {
281                     ipCameraHandler
282                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Manual");
283                 } else {
284                     ipCameraHandler.sendHttpGET(
285                             "/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Manual&Lighting[0][0].MiddleLight[0].Light="
286                                     + command.toString());
287                 }
288                 return;
289             case CHANNEL_AUTO_LED:
290                 if (OnOffType.ON.equals(command)) {
291                     ipCameraHandler.setChannelState(CHANNEL_ENABLE_LED, UnDefType.UNDEF);
292                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&Lighting[0][0].Mode=Auto");
293                 }
294                 return;
295             case CHANNEL_THRESHOLD_AUDIO_ALARM:
296                 int threshold = Math.round(Float.valueOf(command.toString()));
297
298                 if (threshold == 0) {
299                     ipCameraHandler.sendHttpGET(
300                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationThreold=1");
301                 } else {
302                     ipCameraHandler.sendHttpGET(
303                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationThreold=" + threshold);
304                 }
305                 return;
306             case CHANNEL_ENABLE_AUDIO_ALARM:
307                 if (OnOffType.ON.equals(command)) {
308                     ipCameraHandler.sendHttpGET(
309                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationDetect=true&AudioDetect[0].EventHandler.Dejitter=1");
310                 } else {
311                     ipCameraHandler.sendHttpGET(
312                             "/cgi-bin/configManager.cgi?action=setConfig&AudioDetect[0].MutationDetect=false");
313                 }
314                 return;
315             case CHANNEL_ENABLE_LINE_CROSSING_ALARM:
316                 if (OnOffType.ON.equals(command)) {
317                     ipCameraHandler.sendHttpGET(
318                             "/cgi-bin/configManager.cgi?action=setConfig&VideoAnalyseRule[0][1].Enable=true");
319                 } else {
320                     ipCameraHandler.sendHttpGET(
321                             "/cgi-bin/configManager.cgi?action=setConfig&VideoAnalyseRule[0][1].Enable=false");
322                 }
323                 return;
324             case CHANNEL_ENABLE_MOTION_ALARM:
325                 if (OnOffType.ON.equals(command)) {
326                     ipCameraHandler.sendHttpGET(
327                             "/cgi-bin/configManager.cgi?action=setConfig&MotionDetect[0].Enable=true&MotionDetect[0].EventHandler.Dejitter=1");
328                 } else {
329                     ipCameraHandler
330                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&MotionDetect[0].Enable=false");
331                 }
332                 return;
333             case CHANNEL_ACTIVATE_ALARM_OUTPUT:
334                 if (OnOffType.ON.equals(command)) {
335                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[0].Mode=1");
336                 } else {
337                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[0].Mode=0");
338                 }
339                 return;
340             case CHANNEL_ACTIVATE_ALARM_OUTPUT2:
341                 if (OnOffType.ON.equals(command)) {
342                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[1].Mode=1");
343                 } else {
344                     ipCameraHandler.sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&AlarmOut[1].Mode=0");
345                 }
346                 return;
347             case CHANNEL_ENABLE_PRIVACY_MODE:
348                 if (OnOffType.OFF.equals(command)) {
349                     ipCameraHandler
350                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&LeLensMask[0].Enable=false");
351                 } else if (OnOffType.ON.equals(command)) {
352                     ipCameraHandler
353                             .sendHttpGET("/cgi-bin/configManager.cgi?action=setConfig&LeLensMask[0].Enable=true");
354                 }
355                 return;
356         }
357     }
358
359     // If a camera does not need to poll a request as often as snapshots, it can be
360     // added here. Binding steps through the list.
361     public List<String> getLowPriorityRequests() {
362         return List.of();
363     }
364 }