* Fix urls are null until binding restarts.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* Change to using port config.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* automate the ffmpeg output folder to follow the UID.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* spotless fixes.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* Update readme.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* change to using the userdata folder.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* change to better field description.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* Add advanced.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* Add link to docs.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* improve readme.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* improve example path in readme.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* Update bundles/org.openhab.binding.ipcamera/README.md
Cut and paste bandit strikes again. thanks.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
Co-authored-by: Fabian Wolter <github@fabian-wolter.de>
* Change to using ipcamera as folder loc.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
* Improve Ffmpeg motion and refactor to remove compiler warnings.
Signed-off-by: Matthew Skinner <matt@pcmus.com>
Co-authored-by: Fabian Wolter <github@fabian-wolter.de>
String action = content.substring(startIndex, endIndex);
switch (code) {
case "VideoMotion":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
}
break;
case "TakenAwayDetection":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_ITEM_TAKEN);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_ITEM_TAKEN);
}
break;
case "LeftDetection":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_ITEM_LEFT);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_ITEM_LEFT);
}
break;
case "SmartMotionVehicle":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_CAR_ALARM);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_CAR_ALARM);
}
break;
case "SmartMotionHuman":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_HUMAN_ALARM);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_HUMAN_ALARM);
}
break;
case "CrossLineDetection":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_LINE_CROSSING_ALARM);
}
break;
case "AudioMutation":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.audioDetected();
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noAudioDetected();
}
break;
case "FaceDetection":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_FACE_DETECTED);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_FACE_DETECTED);
}
break;
case "ParkingDetection":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.ON);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_PARKING_ALARM, OnOffType.OFF);
}
break;
case "CrossRegionDetection":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.noMotionDetected(CHANNEL_FIELD_DETECTION_ALARM);
}
break;
case "VideoLoss":
case "VideoBlind":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.ON);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_TOO_DARK_ALARM, OnOffType.OFF);
}
break;
case "VideoAbnormalDetection":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.ON);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.OFF);
}
break;
case "VideoUnFocus":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.ON);
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
ipCameraHandler.setChannelState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.OFF);
}
break;
case "AlarmLocal":
- if (action.equals("Start")) {
+ if ("Start".equals(action)) {
if (content.contains("index=0")) {
ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.ON);
} else {
ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT2, OnOffType.ON);
}
- } else if (action.equals("Stop")) {
+ } else if ("Stop".equals(action)) {
if (content.contains("index=0")) {
ipCameraHandler.setChannelState(CHANNEL_EXTERNAL_ALARM_INPUT, OnOffType.OFF);
} else {
BufferedReader bufferedReader = new BufferedReader(errorStreamReader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
+ logger.debug("{}", line);
if (format.equals(FFmpegFormat.RTSP_ALARMS)) {
- logger.debug("{}", line);
if (line.contains("lavfi.")) {
- if (countOfMotions == 4) {
- ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
- } else {
+ // When the number of pixels that change are below the noise floor we need to look
+ // across frames to confirm it is motion and not noise.
+ if (countOfMotions < 10) {// Stop increasing otherwise it will take too long to go OFF.
countOfMotions++;
}
+ if (countOfMotions > 9) {
+ ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
+ } else if (countOfMotions > 4 && ipCameraHandler.motionThreshold.intValue() > 10) {
+ ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
+ } else if (countOfMotions > 3 && ipCameraHandler.motionThreshold.intValue() > 15) {
+ ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
+ } else if (countOfMotions > 2 && ipCameraHandler.motionThreshold.intValue() > 30) {
+ ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
+ } else if (countOfMotions > 0 && ipCameraHandler.motionThreshold.intValue() > 89) {
+ ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
+ countOfMotions = 4;// Used to debounce the Alarm.
+ }
} else if (line.contains("speed=")) {
if (countOfMotions > 0) {
- countOfMotions--;
- countOfMotions--;
+ if (ipCameraHandler.motionThreshold.intValue() > 89) {
+ countOfMotions--;
+ }
+ if (ipCameraHandler.motionThreshold.intValue() > 10) {
+ countOfMotions -= 2;
+ } else {
+ countOfMotions -= 4;
+ }
if (countOfMotions <= 0) {
ipCameraHandler.noMotionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
+ countOfMotions = 0;
}
}
} else if (line.contains("silence_start")) {
} else if (line.contains("silence_end")) {
ipCameraHandler.audioDetected();
}
- } else {
- logger.debug("{}", line);
}
}
}
*/
package org.openhab.binding.ipcamera.internal;
+import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
SNAPSHOT
}
+ public static final BigDecimal BIG_DECIMAL_SCALE_MOTION = new BigDecimal(5000);
+
// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_GROUP = new ThingTypeUID(BINDING_ID, "group");
public static final String GENERIC_THING = "generic";
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
- if (SUPPORTED_THING_TYPES.contains(thingTypeUID) || GROUP_SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
- return true;
- }
- return false;
+ return (SUPPORTED_THING_TYPES.contains(thingTypeUID) || GROUP_SUPPORTED_THING_TYPES.contains(thingTypeUID));
}
@Override
}
String stale = Helper.searchString(authenticate, "stale=\"");
- if (stale.equalsIgnoreCase("true")) {
+ if ("true".equalsIgnoreCase(stale)) {
logger.debug("Camera reported stale=true which normally means the NONCE has expired.");
}
}
private String resolveIndexToPath(String uri) {
- if (!uri.substring(1, 2).equals("i")) {
+ if (!"i".equals(uri.substring(1, 2))) {
return ipCameraGroupHandler.getOutputFolder(Integer.parseInt(uri.substring(1, 2)));
}
return "notFound";
HttpRequest httpRequest = (HttpRequest) msg;
String requestIP = "("
+ ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress() + ")";
- if (!whiteList.contains(requestIP) && !whiteList.equals("DISABLE")) {
+ if (!whiteList.contains(requestIP) && !"DISABLE".equals(whiteList)) {
logger.warn("The request made from {} was not in the whitelist and will be ignored.", requestIP);
return;
} else if (HttpMethod.GET.equals(httpRequest.method())) {
try {
if (msg instanceof HttpRequest) {
HttpRequest httpRequest = (HttpRequest) msg;
- if (!whiteList.equals("DISABLE")) {
+ if (!"DISABLE".equals(whiteList)) {
String requestIP = "("
+ ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress() + ")";
if (!whiteList.contains(requestIP)) {
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.math.BigDecimal;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
private boolean isOnline = false; // Used so only 1 error is logged when a network issue occurs.
private boolean firstAudioAlarm = false;
private boolean firstMotionAlarm = false;
- public Double motionThreshold = 0.0016;
+ public BigDecimal motionThreshold = BigDecimal.ZERO;
public int audioThreshold = 35;
@SuppressWarnings("unused")
private @Nullable StreamServerHandler streamServerHandler;
String usersMotionOptions = cameraConfig.getMotionOptions();
if (usersMotionOptions.startsWith("-")) {
// Need to put the users custom options first in the chain before the motion is detected
- filterOptions += " " + usersMotionOptions + ",select='gte(scene," + motionThreshold
- + ")',metadata=print";
+ filterOptions += " " + usersMotionOptions + ",select='gte(scene,"
+ + motionThreshold.divide(BIG_DECIMAL_SCALE_MOTION) + ")',metadata=print";
} else {
filterOptions = filterOptions + " " + usersMotionOptions + " -vf select='gte(scene,"
- + motionThreshold + ")',metadata=print";
+ + motionThreshold.divide(BIG_DECIMAL_SCALE_MOTION) + ")',metadata=print";
}
} else if (motionAlarmEnabled) {
- filterOptions = filterOptions
- .concat(" -vf select='gte(scene," + motionThreshold + ")',metadata=print");
+ filterOptions = filterOptions.concat(" -vf select='gte(scene,"
+ + motionThreshold.divide(BIG_DECIMAL_SCALE_MOTION) + ")',metadata=print");
}
ffmpegRtspHelper = new Ffmpeg(this, format, cameraConfig.getFfmpegLocation(), inputOptions, input,
filterOptions, "-f null -", cameraConfig.getUser(), cameraConfig.getPassword());
} else if (OnOffType.OFF.equals(command) || DecimalType.ZERO.equals(command)) {
motionAlarmEnabled = false;
noMotionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
- } else {
+ } else if (command instanceof PercentType) {
motionAlarmEnabled = true;
- motionThreshold = Double.valueOf(command.toString());
- motionThreshold = motionThreshold / 10000;
+ motionThreshold = ((PercentType) command).toBigDecimal();
}
setupFfmpegFormat(FFmpegFormat.RTSP_ALARMS);
return;
}
switch (topic) {
case "RuleEngine/CellMotionDetector/Motion":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.motionDetected(CHANNEL_CELL_MOTION_ALARM);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.noMotionDetected(CHANNEL_CELL_MOTION_ALARM);
}
break;
case "VideoSource/MotionAlarm":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.noMotionDetected(CHANNEL_MOTION_ALARM);
}
break;
case "AudioAnalytics/Audio/DetectedSound":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.audioDetected();
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.noAudioDetected();
}
break;
case "RuleEngine/FieldDetector/ObjectsInside":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.noMotionDetected(CHANNEL_FIELD_DETECTION_ALARM);
}
break;
case "RuleEngine/LineDetector/Crossed":
- if (dataName.equals("ObjectId")) {
+ if ("ObjectId".equals(dataName)) {
ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM);
} else {
ipCameraHandler.noMotionDetected(CHANNEL_LINE_CROSSING_ALARM);
}
break;
case "RuleEngine/TamperDetector/Tamper":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TAMPER_ALARM, OnOffType.ON);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TAMPER_ALARM, OnOffType.OFF);
}
break;
case "Device/HardwareFailure/StorageFailure":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_STORAGE_ALARM, OnOffType.ON);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_STORAGE_ALARM, OnOffType.OFF);
}
break;
case "VideoSource/ImageTooDark/AnalyticsService":
case "VideoSource/ImageTooDark/ImagingService":
case "VideoSource/ImageTooDark/RecordingService":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TOO_DARK_ALARM, OnOffType.ON);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TOO_DARK_ALARM, OnOffType.OFF);
}
break;
case "VideoSource/GlobalSceneChange/AnalyticsService":
case "VideoSource/GlobalSceneChange/ImagingService":
case "VideoSource/GlobalSceneChange/RecordingService":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.ON);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_SCENE_CHANGE_ALARM, OnOffType.OFF);
}
break;
case "VideoSource/ImageTooBright/AnalyticsService":
case "VideoSource/ImageTooBright/ImagingService":
case "VideoSource/ImageTooBright/RecordingService":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TOO_BRIGHT_ALARM, OnOffType.ON);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TOO_BRIGHT_ALARM, OnOffType.OFF);
}
break;
case "VideoSource/ImageTooBlurry/AnalyticsService":
case "VideoSource/ImageTooBlurry/ImagingService":
case "VideoSource/ImageTooBlurry/RecordingService":
- if (dataValue.equals("true")) {
+ if ("true".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.ON);
- } else if (dataValue.equals("false")) {
+ } else if ("false".equals(dataValue)) {
ipCameraHandler.changeAlarmState(CHANNEL_TOO_BLURRY_ALARM, OnOffType.OFF);
}
break;
ipAddress = temp.substring(beginIndex, endIndex);
}
String brand = checkForBrand(xml);
- if (brand.equals("onvif")) {
+ if ("onvif".equals(brand)) {
try {
brand = getBrandFromLoginPage(ipAddress);
} catch (IOException e) {
String xml = packet.content().toString(CharsetUtil.UTF_8);
logger.trace("Device replied to discovery with:{}", xml);
String xAddr = Helper.fetchXML(xml, "", "d:XAddrs>");// Foscam <wsdd:XAddrs> and all other brands <d:XAddrs>
- if (!xAddr.equals("")) {
+ if (!xAddr.isEmpty()) {
searchReply(xAddr, xml);
} else if (xml.contains("onvif")) {
logger.info("Possible ONVIF camera found at:{}", packet.sender().getHostString());