2 * Copyright (c) 2010-2024 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
13 package org.openhab.binding.ipcamera.internal;
15 import static org.openhab.binding.ipcamera.internal.IpCameraBindingConstants.*;
17 import java.util.List;
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.thing.binding.ThingHandler;
27 import org.openhab.core.types.Command;
28 import org.openhab.core.types.RefreshType;
29 import org.openhab.core.types.UnDefType;
31 import io.netty.channel.ChannelDuplexHandler;
32 import io.netty.channel.ChannelHandlerContext;
33 import io.netty.util.ReferenceCountUtil;
36 * The {@link FoscamHandler} is responsible for handling commands, which are
37 * sent to one of the channels.
39 * @author Matthew Skinner - Initial contribution
43 public class FoscamHandler extends ChannelDuplexHandler {
44 private IpCameraHandler ipCameraHandler;
45 private String password, username;
47 public FoscamHandler(ThingHandler handler, String username, String password) {
48 ipCameraHandler = (IpCameraHandler) handler;
49 this.username = username;
50 this.password = password;
53 // This handles the incoming http replies back from the camera.
55 public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception {
56 if (msg == null || ctx == null) {
60 String content = msg.toString();
61 ipCameraHandler.logger.trace("HTTP Result back from camera is \t:{}:", content);
62 ////////////// Motion Alarm //////////////
63 if (content.contains("<motionDetectAlarm>")) {
64 if (content.contains("<motionDetectAlarm>0</motionDetectAlarm>")) {
65 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.OFF);
66 } else if (content.contains("<motionDetectAlarm>1</motionDetectAlarm>")) { // Enabled but no alarm
67 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.ON);
68 ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
69 } else if (content.contains("<motionDetectAlarm>2</motionDetectAlarm>")) {// Enabled, alarm on
70 ipCameraHandler.setChannelState(CHANNEL_ENABLE_MOTION_ALARM, OnOffType.ON);
71 ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
75 ////////////// Sound Alarm //////////////
76 if (content.contains("<soundAlarm>0</soundAlarm>")) {
77 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.OFF);
78 ipCameraHandler.setChannelState(CHANNEL_AUDIO_ALARM, OnOffType.OFF);
80 if (content.contains("<soundAlarm>1</soundAlarm>")) {
81 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
82 ipCameraHandler.noAudioDetected();
84 if (content.contains("<soundAlarm>2</soundAlarm>")) {
85 ipCameraHandler.setChannelState(CHANNEL_ENABLE_AUDIO_ALARM, OnOffType.ON);
86 ipCameraHandler.audioDetected();
89 ////////////// Sound Threshold //////////////
90 if (content.contains("<sensitivity>0</sensitivity>")) {
91 ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.ZERO);
93 if (content.contains("<sensitivity>1</sensitivity>")) {
94 ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.valueOf("50"));
96 if (content.contains("<sensitivity>2</sensitivity>")) {
97 ipCameraHandler.setChannelState(CHANNEL_THRESHOLD_AUDIO_ALARM, PercentType.HUNDRED);
100 //////////////// Infrared LED /////////////////////
101 if (content.contains("<infraLedState>0</infraLedState>")) {
102 ipCameraHandler.setChannelState(CHANNEL_ENABLE_LED, OnOffType.OFF);
104 if (content.contains("<infraLedState>1</infraLedState>")) {
105 ipCameraHandler.setChannelState(CHANNEL_ENABLE_LED, OnOffType.ON);
108 if (content.contains("</CGI_Result>")) {
112 ReferenceCountUtil.release(msg);
116 // This handles the commands that come from the Openhab event bus.
117 public void handleCommand(ChannelUID channelUID, Command command) {
118 if (command instanceof RefreshType) {
119 switch (channelUID.getId()) {
120 case CHANNEL_THRESHOLD_AUDIO_ALARM:
121 ipCameraHandler.sendHttpGET(
122 "/cgi-bin/CGIProxy.fcgi?cmd=getAudioAlarmConfig&usr=" + username + "&pwd=" + password);
124 case CHANNEL_ENABLE_AUDIO_ALARM:
125 ipCameraHandler.sendHttpGET(
126 "/cgi-bin/CGIProxy.fcgi?cmd=getAudioAlarmConfig&usr=" + username + "&pwd=" + password);
128 case CHANNEL_ENABLE_MOTION_ALARM:
130 .sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=" + username + "&pwd=" + password);
133 return; // Return as we have handled the refresh command above and don't need to
135 } // end of "REFRESH"
136 switch (channelUID.getId()) {
137 case CHANNEL_ENABLE_LED:
138 // Disable the auto mode first
139 ipCameraHandler.sendHttpGET(
140 "/cgi-bin/CGIProxy.fcgi?cmd=setInfraLedConfig&mode=1&usr=" + username + "&pwd=" + password);
141 ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF);
142 if (DecimalType.ZERO.equals(command) || OnOffType.OFF.equals(command)) {
143 ipCameraHandler.sendHttpGET(
144 "/cgi-bin/CGIProxy.fcgi?cmd=closeInfraLed&usr=" + username + "&pwd=" + password);
146 ipCameraHandler.sendHttpGET(
147 "/cgi-bin/CGIProxy.fcgi?cmd=openInfraLed&usr=" + username + "&pwd=" + password);
150 case CHANNEL_AUTO_LED:
151 if (OnOffType.ON.equals(command)) {
152 ipCameraHandler.setChannelState(CHANNEL_ENABLE_LED, UnDefType.UNDEF);
153 ipCameraHandler.sendHttpGET(
154 "/cgi-bin/CGIProxy.fcgi?cmd=setInfraLedConfig&mode=0&usr=" + username + "&pwd=" + password);
156 ipCameraHandler.sendHttpGET(
157 "/cgi-bin/CGIProxy.fcgi?cmd=setInfraLedConfig&mode=1&usr=" + username + "&pwd=" + password);
160 case CHANNEL_THRESHOLD_AUDIO_ALARM:
161 int value = Math.round(Float.valueOf(command.toString()));
163 ipCameraHandler.sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setAudioAlarmConfig&isEnable=0&usr="
164 + username + "&pwd=" + password);
165 } else if (value <= 33) {
167 .sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setAudioAlarmConfig&isEnable=1&sensitivity=0&usr="
168 + username + "&pwd=" + password);
169 } else if (value <= 66) {
171 .sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setAudioAlarmConfig&isEnable=1&sensitivity=1&usr="
172 + username + "&pwd=" + password);
175 .sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setAudioAlarmConfig&isEnable=1&sensitivity=2&usr="
176 + username + "&pwd=" + password);
179 case CHANNEL_ENABLE_AUDIO_ALARM:
180 if (OnOffType.ON.equals(command)) {
181 if (ipCameraHandler.cameraConfig.getCustomAudioAlarmUrl().isEmpty()) {
182 ipCameraHandler.sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setAudioAlarmConfig&isEnable=1&usr="
183 + username + "&pwd=" + password);
185 ipCameraHandler.sendHttpGET(ipCameraHandler.cameraConfig.getCustomAudioAlarmUrl());
188 ipCameraHandler.sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setAudioAlarmConfig&isEnable=0&usr="
189 + username + "&pwd=" + password);
192 case CHANNEL_ENABLE_MOTION_ALARM:
193 if (OnOffType.ON.equals(command)) {
194 if (ipCameraHandler.cameraConfig.getCustomMotionAlarmUrl().isEmpty()) {
195 ipCameraHandler.sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig&isEnable=1&usr="
196 + username + "&pwd=" + password);
197 ipCameraHandler.sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig1&isEnable=1&usr="
198 + username + "&pwd=" + password);
200 ipCameraHandler.sendHttpGET(ipCameraHandler.cameraConfig.getCustomMotionAlarmUrl());
203 ipCameraHandler.sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig&isEnable=0&usr="
204 + username + "&pwd=" + password);
205 ipCameraHandler.sendHttpGET("/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig1&isEnable=0&usr="
206 + username + "&pwd=" + password);
212 // If a camera does not need to poll a request as often as snapshots, it can be
213 // added here. Binding steps through the list.
214 public List<String> getLowPriorityRequests() {