2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
14 package org.openhab.binding.ipcamera.internal;
16 import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.*;
18 import java.util.ArrayList;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.FFmpegFormat;
23 import org.openhab.binding.ipcamera.internal.handler.IpCameraHandler;
24 import org.openhab.core.library.types.DecimalType;
25 import org.openhab.core.library.types.OnOffType;
26 import org.openhab.core.library.types.PercentType;
27 import org.openhab.core.library.types.StringType;
28 import org.openhab.core.thing.ChannelUID;
29 import org.openhab.core.thing.binding.ThingHandler;
30 import org.openhab.core.types.Command;
31 import org.openhab.core.types.RefreshType;
33 import io.netty.channel.ChannelDuplexHandler;
34 import io.netty.channel.ChannelHandlerContext;
35 import io.netty.util.ReferenceCountUtil;
38 * The {@link InstarHandler} is responsible for handling commands, which are
39 * sent to one of the channels.
41 * @author Matthew Skinner - Initial contribution
45 public class InstarHandler extends ChannelDuplexHandler {
46 private IpCameraHandler ipCameraHandler;
47 private String requestUrl = "Empty";
49 public InstarHandler(ThingHandler thingHandler) {
50 ipCameraHandler = (IpCameraHandler) thingHandler;
53 public void setURL(String url) {
57 // This handles the incoming http replies back from the camera.
59 public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception {
60 if (msg == null || ctx == null) {
66 content = msg.toString();
67 if (content.isEmpty()) {
71 case "/param.cgi?cmd=getinfrared":
72 if (content.contains("var infraredstat=\"auto")) {
73 ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.ON);
75 ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF);
78 case "/param.cgi?cmd=getoverlayattr&-region=1":// Text Overlays
79 if (content.contains("var show_1=\"0\"")) {
80 ipCameraHandler.setChannelState(CHANNEL_TEXT_OVERLAY, StringType.EMPTY);
82 value1 = Helper.searchString(content, "var name_1=\"");
83 if (!value1.isEmpty()) {
84 ipCameraHandler.setChannelState(CHANNEL_TEXT_OVERLAY, StringType.valueOf(value1));
88 case "/cgi-bin/hi3510/param.cgi?cmd=getmdattr":// Motion Alarm
90 if (content.contains("var m1_enable=\"1\"")) {
91 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.ON);
93 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.OFF);
96 case "/cgi-bin/hi3510/param.cgi?cmd=getaudioalarmattr":// Audio Alarm
97 if (content.contains("var aa_enable=\"1\"")) {
98 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
99 value1 = Helper.searchString(content, "var aa_value=\"");
100 if (!value1.isEmpty()) {
101 ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.valueOf(value1));
104 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.OFF);
107 case "param.cgi?cmd=getpirattr":// PIR Alarm
108 if (content.contains("var pir_enable=\"1\"")) {
109 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PIR_ALARM, OnOffType.ON);
111 ipCameraHandler.setChannelState(CHANNEL_ENABLE_PIR_ALARM, OnOffType.OFF);
113 // Reset the Alarm, need to find better place to put this.
114 ipCameraHandler.noMotionDetected(CHANNEL_PIR_ALARM);
116 case "/param.cgi?cmd=getioattr":// External Alarm Input
117 if (content.contains("var io_enable=\"1\"")) {
118 ipCameraHandler.setChannelState(CHANNEL_ENABLE_EXTERNAL_ALARM_INPUT, OnOffType.ON);
120 ipCameraHandler.setChannelState(CHANNEL_ENABLE_EXTERNAL_ALARM_INPUT, OnOffType.OFF);
125 ReferenceCountUtil.release(msg);
129 // This handles the commands that come from the Openhab event bus.
130 public void handleCommand(ChannelUID channelUID, Command command) {
131 if (command instanceof RefreshType) {
132 switch (channelUID.getId()) {
133 case CHANNEL_MOTION_ALARM:
134 if (ipCameraHandler.cameraConfig.getServerPort() > 0) {
135 ipCameraHandler.logger.info("Setting up the Alarm Server settings in the camera now");
136 ipCameraHandler.sendHttpGET(
137 "/param.cgi?cmd=setmdalarm&-aname=server2&-switch=on&-interval=1&cmd=setalarmserverattr&-as_index=3&-as_server="
138 + ipCameraHandler.hostIp + "&-as_port="
139 + ipCameraHandler.cameraConfig.getServerPort()
140 + "&-as_path=/instar&-as_queryattr1=&-as_queryval1=&-as_queryattr2=&-as_queryval2=&-as_queryattr3=&-as_queryval3=&-as_activequery=1&-as_auth=0&-as_query1=0&-as_query2=0&-as_query3=0");
145 } // end of "REFRESH"
146 switch (channelUID.getId()) {
147 case CHANNEL_THRESHOLD_AUDIO_ALARM:
148 int value = Math.round(Float.valueOf(command.toString()));
150 ipCameraHandler.sendHttpGET("/cgi-bin/hi3510/param.cgi?cmd=setaudioalarmattr&-aa_enable=0");
152 ipCameraHandler.sendHttpGET("/cgi-bin/hi3510/param.cgi?cmd=setaudioalarmattr&-aa_enable=1");
154 .sendHttpGET("/cgi-bin/hi3510/param.cgi?cmd=setaudioalarmattr&-aa_enable=1&-aa_value="
155 + command.toString());
158 case CHANNEL_ENABLE_AUDIO_ALARM:
159 if (OnOffType.ON.equals(command)) {
160 ipCameraHandler.sendHttpGET("/cgi-bin/hi3510/param.cgi?cmd=setaudioalarmattr&-aa_enable=1");
162 ipCameraHandler.sendHttpGET("/cgi-bin/hi3510/param.cgi?cmd=setaudioalarmattr&-aa_enable=0");
165 case CHANNEL_ENABLE_MOTION_ALARM:
166 if (OnOffType.ON.equals(command)) {
167 ipCameraHandler.sendHttpGET(
168 "/cgi-bin/hi3510/param.cgi?cmd=setmdattr&-enable=1&-name=1&cmd=setmdattr&-enable=1&-name=2&cmd=setmdattr&-enable=1&-name=3&cmd=setmdattr&-enable=1&-name=4");
170 ipCameraHandler.sendHttpGET(
171 "/cgi-bin/hi3510/param.cgi?cmd=setmdattr&-enable=0&-name=1&cmd=setmdattr&-enable=0&-name=2&cmd=setmdattr&-enable=0&-name=3&cmd=setmdattr&-enable=0&-name=4");
174 case CHANNEL_TEXT_OVERLAY:
175 String text = Helper.encodeSpecialChars(command.toString());
176 if (text.isEmpty()) {
177 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setoverlayattr&-region=1&-show=0");
179 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setoverlayattr&-region=1&-show=1&-name=" + text);
182 case CHANNEL_AUTO_LED:
183 if (OnOffType.ON.equals(command)) {
184 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setinfrared&-infraredstat=auto");
186 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setinfrared&-infraredstat=close");
189 case CHANNEL_ENABLE_PIR_ALARM:
190 if (OnOffType.ON.equals(command)) {
191 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setpirattr&-pir_enable=1");
193 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setpirattr&-pir_enable=0");
196 case CHANNEL_ENABLE_EXTERNAL_ALARM_INPUT:
197 if (OnOffType.ON.equals(command)) {
198 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setioattr&-io_enable=1");
200 ipCameraHandler.sendHttpGET("/param.cgi?cmd=setioattr&-io_enable=0");
203 case CHANNEL_FFMPEG_MOTION_CONTROL:
204 if (OnOffType.ON.equals(command)) {
205 ipCameraHandler.motionAlarmEnabled = true;
206 } else if (OnOffType.OFF.equals(command) || DecimalType.ZERO.equals(command)) {
207 ipCameraHandler.motionAlarmEnabled = false;
208 ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
210 ipCameraHandler.motionAlarmEnabled = true;
211 ipCameraHandler.motionThreshold = Double.valueOf(command.toString());
212 ipCameraHandler.motionThreshold = ipCameraHandler.motionThreshold / 10000;
214 ipCameraHandler.setupFfmpegFormat(FFmpegFormat.RTSP_ALARMS);
219 void alarmTriggered(String alarm) {
220 ipCameraHandler.logger.debug("Alarm has been triggered:{}", alarm);
222 case "/instar?&active=1":// The motion area boxes 1-4
223 case "/instar?&active=2":
224 case "/instar?&active=3":
225 case "/instar?&active=4":
226 ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
228 case "/instar?&active=5":// PIR
229 ipCameraHandler.motionDetected(CHANNEL_PIR_ALARM);
231 case "/instar?&active=6":// Audio Alarm
232 ipCameraHandler.audioDetected();
234 case "/instar?&active=7":// Motion Area 1
235 case "/instar?&active=8":// Motion Area 2
236 case "/instar?&active=9":// Motion Area 3
237 case "/instar?&active=10":// Motion Area 4
238 ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
243 // If a camera does not need to poll a request as often as snapshots, it can be
244 // added here. Binding steps through the list.
245 public ArrayList<String> getLowPriorityRequests() {
246 ArrayList<String> lowPriorityRequests = new ArrayList<String>(2);
247 lowPriorityRequests.add("/cgi-bin/hi3510/param.cgi?cmd=getaudioalarmattr");
248 lowPriorityRequests.add("/cgi-bin/hi3510/param.cgi?cmd=getmdattr");
249 lowPriorityRequests.add("/param.cgi?cmd=getinfrared");
250 lowPriorityRequests.add("/param.cgi?cmd=getoverlayattr&-region=1");
251 lowPriorityRequests.add("/param.cgi?cmd=getpirattr");
252 lowPriorityRequests.add("/param.cgi?cmd=getioattr"); // ext alarm input on/off
253 // lowPriorityRequests.add("/param.cgi?cmd=getserverinfo");
254 return lowPriorityRequests;