[ipcamera] Fix warnings and improve logging (#15703)

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer 2023-10-17 16:03:25 +02:00 committed by GitHub
parent 7cb94f9238
commit 1e090bddae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 121 additions and 142 deletions

View File

@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
/** /**
* The {@link Ffmpeg} class is responsible for handling multiple ffmpeg conversions which are used for many tasks * The {@link Ffmpeg} class is responsible for handling multiple ffmpeg conversions which are used for many tasks
* *
*
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@ -82,7 +81,7 @@ public class Ffmpeg {
public void setKeepAlive(int numberOfEightSeconds) { public void setKeepAlive(int numberOfEightSeconds) {
// We poll every 8 seconds due to mjpeg stream requirement. // We poll every 8 seconds due to mjpeg stream requirement.
if (keepAlive == -1 && numberOfEightSeconds > 1) { if (keepAlive == -1 && numberOfEightSeconds > 1) {
return;// When set to -1 this will not auto turn off stream. return; // When set to -1 this will not auto turn off stream.
} }
keepAlive = numberOfEightSeconds; keepAlive = numberOfEightSeconds;
} }
@ -90,7 +89,7 @@ public class Ffmpeg {
public void checkKeepAlive() { public void checkKeepAlive() {
if (keepAlive == 1) { if (keepAlive == 1) {
stopConverting(); stopConverting();
} else if (keepAlive <= -1 && !getIsAlive()) { } else if (keepAlive <= -1 && !isAlive()) {
logger.warn("HLS stream was not running, restarting it now."); logger.warn("HLS stream was not running, restarting it now.");
startConverting(); startConverting();
} }
@ -124,9 +123,8 @@ public class Ffmpeg {
public void run() { public void run() {
try { try {
process = Runtime.getRuntime().exec(commandArrayList.toArray(new String[commandArrayList.size()])); process = Runtime.getRuntime().exec(commandArrayList.toArray(new String[commandArrayList.size()]));
Process localProcess = process;
if (localProcess != null) { InputStream errorStream = process.getErrorStream();
InputStream errorStream = localProcess.getErrorStream();
InputStreamReader errorStreamReader = new InputStreamReader(errorStream); InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
BufferedReader bufferedReader = new BufferedReader(errorStreamReader); BufferedReader bufferedReader = new BufferedReader(errorStreamReader);
String line = null; String line = null;
@ -137,7 +135,7 @@ public class Ffmpeg {
if (line.contains("lavfi.")) { if (line.contains("lavfi.")) {
// When the number of pixels that change are below the noise floor we need to look // 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. // across frames to confirm it is motion and not noise.
if (countOfMotions < 10) {// Stop increasing otherwise it takes too long to go OFF if (countOfMotions < 10) { // Stop increasing otherwise it takes too long to go OFF
countOfMotions++; countOfMotions++;
} }
if (countOfMotions > 9) { if (countOfMotions > 9) {
@ -150,7 +148,7 @@ public class Ffmpeg {
ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
} else if (countOfMotions > 0 && ipCameraHandler.motionThreshold.intValue() > 89) { } else if (countOfMotions > 0 && ipCameraHandler.motionThreshold.intValue() > 89) {
ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM);
countOfMotions = 4;// Used to debounce the Alarm. countOfMotions = 4; // Used to debounce the Alarm.
} }
} else if (line.contains("speed=")) { } else if (line.contains("speed=")) {
if (countOfMotions > 0) { if (countOfMotions > 0) {
@ -174,15 +172,14 @@ public class Ffmpeg {
} }
case MJPEG: case MJPEG:
case SNAPSHOT: case SNAPSHOT:
notFrozen = true;// RTSP_ALARMS, MJPEG and SNAPSHOT all set this to true, no break. notFrozen = true; // RTSP_ALARMS, MJPEG and SNAPSHOT all set this to true, no break.
break; break;
default: default:
break; break;
} }
} }
}
} catch (IOException e) { } catch (IOException e) {
logger.warn("An IO error occured trying to start FFmpeg:{}", e.getMessage()); logger.warn("An IO error occurred trying to start FFmpeg: {}", e.getMessage());
} finally { } finally {
switch (format) { switch (format) {
case GIF: case GIF:
@ -202,10 +199,10 @@ public class Ffmpeg {
if (!ipCameraFfmpegThread.isAlive()) { if (!ipCameraFfmpegThread.isAlive()) {
ipCameraFfmpegThread = new IpCameraFfmpegThread(); ipCameraFfmpegThread = new IpCameraFfmpegThread();
if (!password.isEmpty()) { if (!password.isEmpty()) {
logger.debug("Starting ffmpeg with this command now:{}", logger.debug("Starting ffmpeg with this command now: {}",
ffmpegCommand.replaceAll(password, "********")); ffmpegCommand.replaceAll(password, "********"));
} else { } else {
logger.debug("Starting ffmpeg with this command now:{}", ffmpegCommand); logger.debug("Starting ffmpeg with this command now: {}", ffmpegCommand);
} }
ipCameraFfmpegThread.start(); ipCameraFfmpegThread.start();
if (format.equals(FFmpegFormat.HLS)) { if (format.equals(FFmpegFormat.HLS)) {
@ -217,7 +214,7 @@ public class Ffmpeg {
} }
} }
public boolean getIsAlive() { public boolean isAlive() {
Process localProcess = process; Process localProcess = process;
if (localProcess != null) { if (localProcess != null) {
if (localProcess.isAlive() && notFrozen) { if (localProcess.isAlive() && notFrozen) {
@ -230,7 +227,7 @@ public class Ffmpeg {
public void stopConverting() { public void stopConverting() {
if (ipCameraFfmpegThread.isAlive()) { if (ipCameraFfmpegThread.isAlive()) {
logger.debug("Stopping ffmpeg {} now when keepalive is:{}", format, keepAlive); logger.debug("Stopping ffmpeg {} now when keepalive is: {}", format, keepAlive);
Process localProcess = process; Process localProcess = process;
if (localProcess != null) { if (localProcess != null) {
localProcess.destroyForcibly(); localProcess.destroyForcibly();

View File

@ -120,13 +120,11 @@ public class ReolinkHandler extends ChannelDuplexHandler {
ipCameraHandler.logger.debug("The GetAiStateResponse could not be parsed"); ipCameraHandler.logger.debug("The GetAiStateResponse could not be parsed");
return; return;
} }
if (aiResponse[0].value.dog_cat != null) {
if (aiResponse[0].value.dog_cat.alarm_state == 1) { if (aiResponse[0].value.dog_cat.alarm_state == 1) {
ipCameraHandler.setChannelState(CHANNEL_ANIMAL_ALARM, OnOffType.ON); ipCameraHandler.setChannelState(CHANNEL_ANIMAL_ALARM, OnOffType.ON);
} else { } else {
ipCameraHandler.setChannelState(CHANNEL_ANIMAL_ALARM, OnOffType.OFF); ipCameraHandler.setChannelState(CHANNEL_ANIMAL_ALARM, OnOffType.OFF);
} }
}
if (aiResponse[0].value.face.alarm_state == 1) { if (aiResponse[0].value.face.alarm_state == 1) {
ipCameraHandler.setChannelState(CHANNEL_FACE_DETECTED, OnOffType.ON); ipCameraHandler.setChannelState(CHANNEL_FACE_DETECTED, OnOffType.ON);
} else { } else {

View File

@ -50,7 +50,6 @@ import org.slf4j.LoggerFactory;
* *
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
public class IpCameraGroupHandler extends BaseThingHandler { public class IpCameraGroupHandler extends BaseThingHandler {
private final Logger logger = LoggerFactory.getLogger(getClass()); private final Logger logger = LoggerFactory.getLogger(getClass());

View File

@ -123,7 +123,6 @@ import io.netty.util.concurrent.GlobalEventExecutor;
* *
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
public class IpCameraHandler extends BaseThingHandler { public class IpCameraHandler extends BaseThingHandler {
public final Logger logger = LoggerFactory.getLogger(getClass()); public final Logger logger = LoggerFactory.getLogger(getClass());
@ -245,7 +244,7 @@ public class IpCameraHandler extends BaseThingHandler {
mjpegContentType = contentType; mjpegContentType = contentType;
CameraServlet localServlet = servlet; CameraServlet localServlet = servlet;
if (localServlet != null) { if (localServlet != null) {
logger.debug("Setting Content-Type to:{}", contentType); logger.debug("Setting Content-Type to: {}", contentType);
localServlet.openStreams.updateContentType(contentType, boundary); localServlet.openStreams.updateContentType(contentType, boundary);
} }
} }
@ -384,7 +383,7 @@ public class IpCameraHandler extends BaseThingHandler {
return; // don't auto close this as it is for the alarms. return; // don't auto close this as it is for the alarms.
} }
} }
logger.debug("Closing an idle channel for camera:{}", cameraConfig.getIp()); logger.debug("Closing an idle channel for camera: {}", cameraConfig.getIp());
ctx.close(); ctx.close();
} }
} }
@ -511,15 +510,15 @@ public class IpCameraHandler extends BaseThingHandler {
} }
private void checkCameraConnection() { private void checkCameraConnection() {
if (snapshotPolling) {// Currently polling a real URL for snapshots, so camera must be online. if (snapshotPolling) { // Currently polling a real URL for snapshots, so camera must be online.
return; return;
} else if (ffmpegSnapshotGeneration) {// Use RTSP stream creating snapshots to know camera is online. } else if (ffmpegSnapshotGeneration) { // Use RTSP stream creating snapshots to know camera is online.
Ffmpeg localSnapshot = ffmpegSnapshot; Ffmpeg localSnapshot = ffmpegSnapshot;
if (localSnapshot != null && !localSnapshot.getIsAlive()) { if (localSnapshot != null && !localSnapshot.isAlive()) {
cameraCommunicationError("FFmpeg Snapshots Stopped: Check your camera can be reached."); cameraCommunicationError("FFmpeg Snapshots Stopped: Check that your camera can be reached.");
return; return;
} }
return;// ffmpeg snapshot stream is still alive return; // ffmpeg snapshot stream is still alive
} }
// if ONVIF cam also use connection state which is updated by regular messages to camera // if ONVIF cam also use connection state which is updated by regular messages to camera
@ -614,7 +613,7 @@ public class IpCameraHandler extends BaseThingHandler {
if (!basicAuth.isEmpty()) { if (!basicAuth.isEmpty()) {
if (useDigestAuth) { if (useDigestAuth) {
logger.warn("Camera at IP:{} had both Basic and Digest set to be used", cameraConfig.getIp()); logger.warn("Camera at IP: {} had both Basic and Digest set to be used", cameraConfig.getIp());
setBasicAuth(false); setBasicAuth(false);
} else { } else {
request.headers().set("Authorization", "Basic " + basicAuth); request.headers().set("Authorization", "Basic " + basicAuth);
@ -755,7 +754,7 @@ public class IpCameraHandler extends BaseThingHandler {
channelTrackingMap.remove(channelTracking.getRequestUrl()); channelTrackingMap.remove(channelTracking.getRequestUrl());
} }
if (channelTracking.getChannel().equals(channel)) { if (channelTracking.getChannel().equals(channel)) {
logger.debug("Open channel to camera is used for URL:{}", channelTracking.getRequestUrl()); logger.debug("Open channel to camera is used for URL: {}", channelTracking.getRequestUrl());
oldChannel = false; oldChannel = false;
} }
} }
@ -882,9 +881,7 @@ public class IpCameraHandler extends BaseThingHandler {
ffmpegRecord = new Ffmpeg(this, format, cameraConfig.getFfmpegLocation(), inputOptions, rtspUri, ffmpegRecord = new Ffmpeg(this, format, cameraConfig.getFfmpegLocation(), inputOptions, rtspUri,
cameraConfig.getMp4OutOptions(), cameraConfig.getFfmpegOutput() + mp4Filename + ".mp4", cameraConfig.getMp4OutOptions(), cameraConfig.getFfmpegOutput() + mp4Filename + ".mp4",
cameraConfig.getUser(), cameraConfig.getPassword()); cameraConfig.getUser(), cameraConfig.getPassword());
Ffmpeg localRecord = ffmpegRecord; ffmpegRecord.startConverting();
if (localRecord != null) {
localRecord.startConverting();
if (mp4History.isEmpty()) { if (mp4History.isEmpty()) {
mp4History = mp4Filename; mp4History = mp4Filename;
} else if (!"ipcamera".equals(mp4Filename)) { } else if (!"ipcamera".equals(mp4Filename)) {
@ -894,7 +891,6 @@ public class IpCameraHandler extends BaseThingHandler {
mp4History = mp4History.substring(0, endIndex); mp4History = mp4History.substring(0, endIndex);
} }
} }
}
setChannelState(CHANNEL_MP4_HISTORY, new StringType(mp4History)); setChannelState(CHANNEL_MP4_HISTORY, new StringType(mp4History));
break; break;
case RTSP_ALARMS: case RTSP_ALARMS:
@ -930,10 +926,7 @@ public class IpCameraHandler extends BaseThingHandler {
} }
ffmpegRtspHelper = new Ffmpeg(this, format, cameraConfig.getFfmpegLocation(), inputOptions, input, ffmpegRtspHelper = new Ffmpeg(this, format, cameraConfig.getFfmpegLocation(), inputOptions, input,
filterOptions, "-f null -", cameraConfig.getUser(), cameraConfig.getPassword()); filterOptions, "-f null -", cameraConfig.getUser(), cameraConfig.getPassword());
localAlarms = ffmpegRtspHelper; ffmpegRtspHelper.startConverting();
if (localAlarms != null) {
localAlarms.startConverting();
}
break; break;
case MJPEG: case MJPEG:
if (ffmpegMjpeg == null) { if (ffmpegMjpeg == null) {
@ -1429,7 +1422,7 @@ public class IpCameraHandler extends BaseThingHandler {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Camera refused connection on ONVIF ports."); "Camera refused connection on ONVIF ports.");
} }
logger.debug("About to connect to the IP Camera using the ONVIF PORT at IP:{}:{}", cameraConfig.getIp(), logger.debug("About to connect to the IP Camera using the ONVIF PORT at IP: {}:{}", cameraConfig.getIp(),
cameraConfig.getOnvifPort()); cameraConfig.getOnvifPort());
onvifCamera.connect(thing.getThingTypeUID().getId().equals(ONVIF_THING)); onvifCamera.connect(thing.getThingTypeUID().getId().equals(ONVIF_THING));
return; return;
@ -1448,7 +1441,7 @@ public class IpCameraHandler extends BaseThingHandler {
} }
public void cameraConfigError(String reason) { public void cameraConfigError(String reason) {
// wont try to reconnect again due to a config error being the cause. // won't try to reconnect again due to a config error being the cause.
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, reason); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, reason);
dispose(); dispose();
} }
@ -1456,7 +1449,7 @@ public class IpCameraHandler extends BaseThingHandler {
public void cameraCommunicationError(String reason) { public void cameraCommunicationError(String reason) {
// will try to reconnect again as camera may be rebooting. // will try to reconnect again as camera may be rebooting.
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason);
if (isOnline) {// if already offline dont try reconnecting in 6 seconds, we want 30sec wait. if (isOnline) { // if already offline dont try reconnecting in 6 seconds, we want 30sec wait.
resetAndRetryConnecting(); resetAndRetryConnecting();
} }
} }
@ -1640,13 +1633,13 @@ public class IpCameraHandler extends BaseThingHandler {
} }
if (ffmpegMotionAlarmEnabled || ffmpegAudioAlarmEnabled) { if (ffmpegMotionAlarmEnabled || ffmpegAudioAlarmEnabled) {
localFfmpeg = ffmpegRtspHelper; localFfmpeg = ffmpegRtspHelper;
if (localFfmpeg == null || !localFfmpeg.getIsAlive()) { if (localFfmpeg == null || !localFfmpeg.isAlive()) {
setupFfmpegFormat(FFmpegFormat.RTSP_ALARMS); setupFfmpegFormat(FFmpegFormat.RTSP_ALARMS);
} }
} }
// check if the thread has frozen due to camera doing a soft reboot // check if the thread has frozen due to camera doing a soft reboot
localFfmpeg = ffmpegMjpeg; localFfmpeg = ffmpegMjpeg;
if (localFfmpeg != null && !localFfmpeg.getIsAlive()) { if (localFfmpeg != null && !localFfmpeg.isAlive()) {
logger.debug("MJPEG was not being produced by FFmpeg when it should have been, restarting FFmpeg."); logger.debug("MJPEG was not being produced by FFmpeg when it should have been, restarting FFmpeg.");
setupFfmpegFormat(FFmpegFormat.MJPEG); setupFfmpegFormat(FFmpegFormat.MJPEG);
} }
@ -1871,7 +1864,7 @@ public class IpCameraHandler extends BaseThingHandler {
localFfmpeg.stopConverting(); localFfmpeg.stopConverting();
ffmpegSnapshot = null; ffmpegSnapshot = null;
} }
if (!thing.getThingTypeUID().getId().equals(GENERIC_THING)) {// generic cameras do not have ONVIF support if (!thing.getThingTypeUID().getId().equals(GENERIC_THING)) { // generic cameras do not have ONVIF support
onvifCamera.disconnect(); onvifCamera.disconnect();
} }
openChannels.close(); openChannels.close();

View File

@ -28,7 +28,6 @@ import io.netty.util.ReferenceCountUtil;
/** /**
* The {@link OnvifCodec} is used by Netty to decode Onvif traffic into message Strings. * The {@link OnvifCodec} is used by Netty to decode Onvif traffic into message Strings.
* *
*
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
@ -66,11 +65,11 @@ public class OnvifCodec extends ChannelDuplexHandler {
} }
if (evt instanceof IdleStateEvent) { if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt; IdleStateEvent e = (IdleStateEvent) evt;
logger.trace("IdleStateEvent received {}", e.state()); logger.trace("IdleStateEvent received: {}", e.state());
onvifConnection.setIsConnected(false); onvifConnection.setIsConnected(false);
ctx.close(); ctx.close();
} else { } else {
logger.trace("Other ONVIF netty channel event occured {}", evt); logger.trace("Other ONVIF netty channel event occurred: {}", evt);
} }
} }

View File

@ -67,8 +67,6 @@ import io.netty.handler.timeout.IdleStateHandler;
/** /**
* The {@link OnvifConnection} This is a basic Netty implementation for connecting and communicating to ONVIF cameras. * The {@link OnvifConnection} This is a basic Netty implementation for connecting and communicating to ONVIF cameras.
* *
*
*
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@ -146,7 +144,7 @@ public class OnvifConnection {
private Float tiltRangeMax = 1.0f; private Float tiltRangeMax = 1.0f;
private Float zoomMin = 0.0f; private Float zoomMin = 0.0f;
private Float zoomMax = 1.0f; private Float zoomMax = 1.0f;
// These hold the PTZ values for updating Openhabs controls in 0-100 range // These hold the PTZ values for updating openHABs controls in 0-100 range
private Float currentPanPercentage = 0.0f; private Float currentPanPercentage = 0.0f;
private Float currentTiltPercentage = 0.0f; private Float currentTiltPercentage = 0.0f;
private Float currentZoomPercentage = 0.0f; private Float currentZoomPercentage = 0.0f;
@ -308,7 +306,7 @@ public class OnvifConnection {
} }
public void processReply(String message) { public void processReply(String message) {
logger.trace("Onvif reply is:{}", message); logger.trace("ONVIF reply is: {}", message);
if (message.contains("PullMessagesResponse")) { if (message.contains("PullMessagesResponse")) {
eventRecieved(message); eventRecieved(message);
} else if (message.contains("RenewResponse")) { } else if (message.contains("RenewResponse")) {
@ -317,7 +315,7 @@ public class OnvifConnection {
setIsConnected(true); setIsConnected(true);
sendOnvifRequest(RequestType.GetCapabilities, deviceXAddr); sendOnvifRequest(RequestType.GetCapabilities, deviceXAddr);
parseDateAndTime(message); parseDateAndTime(message);
logger.debug("Openhabs UTC dateTime is:{}", getUTCdateTime()); logger.debug("openHAB UTC dateTime is: {}", getUTCdateTime());
} else if (message.contains("GetCapabilitiesResponse")) {// 2nd to be sent. } else if (message.contains("GetCapabilitiesResponse")) {// 2nd to be sent.
parseXAddr(message); parseXAddr(message);
sendOnvifRequest(RequestType.GetProfiles, mediaXAddr); sendOnvifRequest(RequestType.GetProfiles, mediaXAddr);
@ -358,7 +356,7 @@ public class OnvifConnection {
logger.debug("ptzNodeToken={}", ptzNodeToken); logger.debug("ptzNodeToken={}", ptzNodeToken);
sendPTZRequest(RequestType.GetConfigurations); sendPTZRequest(RequestType.GetConfigurations);
} else if (message.contains("GetDeviceInformationResponse")) { } else if (message.contains("GetDeviceInformationResponse")) {
logger.debug("GetDeviceInformationResponse recieved"); logger.debug("GetDeviceInformationResponse received");
} else if (message.contains("GetSnapshotUriResponse")) { } else if (message.contains("GetSnapshotUriResponse")) {
snapshotUri = removeIPfromUrl(Helper.fetchXML(message, ":MediaUri", ":Uri")); snapshotUri = removeIPfromUrl(Helper.fetchXML(message, ":MediaUri", ":Uri"));
logger.debug("GetSnapshotUri:{}", snapshotUri); logger.debug("GetSnapshotUri:{}", snapshotUri);
@ -387,7 +385,7 @@ public class OnvifConnection {
index = url.indexOf("/", index + 2); index = url.indexOf("/", index + 2);
} }
if (index == -1) { if (index == -1) {
logger.debug("We hit an issue parsing url:{}", url); logger.debug("We hit an issue parsing url: {}", url);
return ""; return "";
} }
return url.substring(index); return url.substring(index);
@ -399,7 +397,7 @@ public class OnvifConnection {
if (startIndex != -1 && endIndex != -1) { if (startIndex != -1 && endIndex != -1) {
return url.substring(startIndex, endIndex); return url.substring(startIndex, endIndex);
} }
logger.debug("We hit an issue extracting IP:PORT from url:{}", url); logger.debug("We hit an issue extracting IP:PORT from url: {}", url);
return ""; return "";
} }
@ -421,17 +419,17 @@ public class OnvifConnection {
String temp = Helper.fetchXML(message, "<tt:Device", "tt:XAddr"); String temp = Helper.fetchXML(message, "<tt:Device", "tt:XAddr");
if (!temp.isEmpty()) { if (!temp.isEmpty()) {
deviceXAddr = temp; deviceXAddr = temp;
logger.debug("deviceXAddr:{}", deviceXAddr); logger.debug("deviceXAddr: {}", deviceXAddr);
} }
temp = Helper.fetchXML(message, "<tt:Events", "tt:XAddr"); temp = Helper.fetchXML(message, "<tt:Events", "tt:XAddr");
if (!temp.isEmpty()) { if (!temp.isEmpty()) {
subscriptionXAddr = eventXAddr = temp; subscriptionXAddr = eventXAddr = temp;
logger.debug("eventsXAddr:{}", eventXAddr); logger.debug("eventsXAddr: {}", eventXAddr);
} }
temp = Helper.fetchXML(message, "<tt:Media", "tt:XAddr"); temp = Helper.fetchXML(message, "<tt:Media", "tt:XAddr");
if (!temp.isEmpty()) { if (!temp.isEmpty()) {
mediaXAddr = temp; mediaXAddr = temp;
logger.debug("mediaXAddr:{}", mediaXAddr); logger.debug("mediaXAddr: {}", mediaXAddr);
} }
ptzXAddr = Helper.fetchXML(message, "<tt:PTZ", "tt:XAddr"); ptzXAddr = Helper.fetchXML(message, "<tt:PTZ", "tt:XAddr");
@ -453,7 +451,7 @@ public class OnvifConnection {
} }
ipCameraHandler.removeChannels(removeChannels); ipCameraHandler.removeChannels(removeChannels);
} else { } else {
logger.debug("ptzXAddr:{}", ptzXAddr); logger.debug("ptzXAddr: {}", ptzXAddr);
} }
} }
@ -464,7 +462,7 @@ public class OnvifConnection {
String day = Helper.fetchXML(message, "UTCDateTime", "Day>"); String day = Helper.fetchXML(message, "UTCDateTime", "Day>");
String month = Helper.fetchXML(message, "UTCDateTime", "Month>"); String month = Helper.fetchXML(message, "UTCDateTime", "Month>");
String year = Helper.fetchXML(message, "UTCDateTime", "Year>"); String year = Helper.fetchXML(message, "UTCDateTime", "Year>");
logger.debug("Cameras UTC dateTime is:{}-{}-{}T{}:{}:{}", year, month, day, hour, minute, second); logger.debug("Camera UTC dateTime is: {}-{}-{}T{}:{}:{}", year, month, day, hour, minute, second);
} }
private String getUTCdateTime() { private String getUTCdateTime() {
@ -497,7 +495,7 @@ public class OnvifConnection {
} }
public void sendOnvifRequest(RequestType requestType, String xAddr) { public void sendOnvifRequest(RequestType requestType, String xAddr) {
logger.trace("Sending ONVIF request:{}", requestType); logger.trace("Sending ONVIF request: {}", requestType);
String security = ""; String security = "";
String extraEnvelope = ""; String extraEnvelope = "";
String headerTo = ""; String headerTo = "";
@ -565,7 +563,7 @@ public class OnvifConnection {
bootstrap = localBootstap; bootstrap = localBootstap;
} }
if (!mainEventLoopGroup.isShuttingDown()) { if (!mainEventLoopGroup.isShuttingDown()) {
bootstrap.connect(new InetSocketAddress(ipAddress, onvifPort)).addListener(new ChannelFutureListener() { localBootstap.connect(new InetSocketAddress(ipAddress, onvifPort)).addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(@Nullable ChannelFuture future) { public void operationComplete(@Nullable ChannelFuture future) {
@ -576,15 +574,16 @@ public class OnvifConnection {
connectError = false; connectError = false;
Channel ch = future.channel(); Channel ch = future.channel();
ch.writeAndFlush(request); ch.writeAndFlush(request);
} else { // an error occured } else { // an error occurred
if (future.isDone() && !future.isCancelled()) { if (future.isDone() && !future.isCancelled()) {
Throwable cause = future.cause(); Throwable cause = future.cause();
String msg = cause.getMessage();
logger.trace("connect failed - cause {}", cause.getMessage()); logger.trace("connect failed - cause {}", cause.getMessage());
if (cause instanceof ConnectTimeoutException) { if (cause instanceof ConnectTimeoutException) {
logger.debug("Camera is not reachable on IP {}", ipAddress); logger.debug("Camera is not reachable on IP {}", ipAddress);
connectError = true; connectError = true;
} else if ((cause instanceof ConnectException) } else if ((cause instanceof ConnectException) && msg != null
&& cause.getMessage().contains("Connection refused")) { && msg.contains("Connection refused")) {
logger.debug("Camera ONVIF port {} is refused.", onvifPort); logger.debug("Camera ONVIF port {} is refused.", onvifPort);
refusedError = true; refusedError = true;
} }
@ -616,7 +615,7 @@ public class OnvifConnection {
} else {// 192.168.1.1 } else {// 192.168.1.1
ipAddress = url; ipAddress = url;
deviceXAddr = "http://" + ipAddress + "/onvif/device_service"; deviceXAddr = "http://" + ipAddress + "/onvif/device_service";
logger.debug("No Onvif Port found when parsing:{}", url); logger.debug("No ONVIF Port found when parsing: {}", url);
return; return;
} }
deviceXAddr = "http://" + ipAddress + ":" + onvifPort + "/onvif/device_service"; deviceXAddr = "http://" + ipAddress + ":" + onvifPort + "/onvif/device_service";
@ -644,7 +643,7 @@ public class OnvifConnection {
} }
String dataName = Helper.fetchXML(eventMessage, "tt:Data", "Name=\""); String dataName = Helper.fetchXML(eventMessage, "tt:Data", "Name=\"");
String dataValue = Helper.fetchXML(eventMessage, "tt:Data", "Value=\""); String dataValue = Helper.fetchXML(eventMessage, "tt:Data", "Value=\"");
logger.debug("Onvif Event Topic:{}, Data:{}, Value:{}", topic, dataName, dataValue); logger.debug("ONVIF Event Topic: {}, Data: {}, Value: {}", topic, dataName, dataValue);
switch (topic) { switch (topic) {
case "RuleEngine/CellMotionDetector/Motion": case "RuleEngine/CellMotionDetector/Motion":
if ("true".equals(dataValue)) { if ("true".equals(dataValue)) {
@ -767,7 +766,7 @@ public class OnvifConnection {
} }
break; break;
default: default:
logger.debug("Please report this camera has an un-implemented ONVIF event. Topic:{}", topic); logger.debug("Please report this camera has an un-implemented ONVIF event. Topic: {}", topic);
} }
sendOnvifRequest(RequestType.Renew, subscriptionXAddr); sendOnvifRequest(RequestType.Renew, subscriptionXAddr);
} }
@ -833,7 +832,7 @@ public class OnvifConnection {
if (startLookingFromIndex >= 0) { if (startLookingFromIndex >= 0) {
temp = Helper.fetchXML(message.substring(startLookingFromIndex), heading, key); temp = Helper.fetchXML(message.substring(startLookingFromIndex), heading, key);
if (!temp.isEmpty()) { if (!temp.isEmpty()) {
logger.trace("String was found:{}", temp); logger.trace("String was found: {}", temp);
results.add(temp); results.add(temp);
} else { } else {
return results;// key string must not exist so stop looking. return results;// key string must not exist so stop looking.
@ -879,7 +878,7 @@ public class OnvifConnection {
currentPanCamValue = Float.parseFloat(result.substring(beginIndex + 3, endIndex)); currentPanCamValue = Float.parseFloat(result.substring(beginIndex + 3, endIndex));
currentPanPercentage = (((panRangeMin - currentPanCamValue) * -1) / ((panRangeMin - panRangeMax) * -1)) currentPanPercentage = (((panRangeMin - currentPanCamValue) * -1) / ((panRangeMin - panRangeMax) * -1))
* 100; * 100;
logger.debug("Pan is updating to:{} and the cam value is {}", Math.round(currentPanPercentage), logger.debug("Pan is updating to: {} and the cam value is {}", Math.round(currentPanPercentage),
currentPanCamValue); currentPanCamValue);
} else { } else {
logger.warn( logger.warn(
@ -893,7 +892,7 @@ public class OnvifConnection {
currentTiltCamValue = Float.parseFloat(result.substring(beginIndex + 3, endIndex)); currentTiltCamValue = Float.parseFloat(result.substring(beginIndex + 3, endIndex));
currentTiltPercentage = (((tiltRangeMin - currentTiltCamValue) * -1) / ((tiltRangeMin - tiltRangeMax) * -1)) currentTiltPercentage = (((tiltRangeMin - currentTiltCamValue) * -1) / ((tiltRangeMin - tiltRangeMax) * -1))
* 100; * 100;
logger.debug("Tilt is updating to:{} and the cam value is {}", Math.round(currentTiltPercentage), logger.debug("Tilt is updating to: {} and the cam value is {}", Math.round(currentTiltPercentage),
currentTiltCamValue); currentTiltCamValue);
} else { } else {
return; return;
@ -904,7 +903,7 @@ public class OnvifConnection {
if (beginIndex >= 0 && endIndex >= 0) { if (beginIndex >= 0 && endIndex >= 0) {
currentZoomCamValue = Float.parseFloat(result.substring(beginIndex + 3, endIndex)); currentZoomCamValue = Float.parseFloat(result.substring(beginIndex + 3, endIndex));
currentZoomPercentage = (((zoomMin - currentZoomCamValue) * -1) / ((zoomMin - zoomMax) * -1)) * 100; currentZoomPercentage = (((zoomMin - currentZoomCamValue) * -1) / ((zoomMin - zoomMax) * -1)) * 100;
logger.debug("Zoom is updating to:{} and the cam value is {}", Math.round(currentZoomPercentage), logger.debug("Zoom is updating to: {} and the cam value is {}", Math.round(currentZoomPercentage),
currentZoomCamValue); currentZoomCamValue);
} else { } else {
return; return;
@ -974,7 +973,7 @@ public class OnvifConnection {
} catch (InterruptedException e) { } catch (InterruptedException e) {
logger.warn("ONVIF was not cleanly shutdown, due to being interrupted"); logger.warn("ONVIF was not cleanly shutdown, due to being interrupted");
} finally { } finally {
logger.debug("Eventloop is shutdown:{}", mainEventLoopGroup.isShutdown()); logger.debug("Eventloop is shutdown: {}", mainEventLoopGroup.isShutdown());
bootstrap = null; bootstrap = null;
threadPool.shutdown(); threadPool.shutdown();
} }

View File

@ -61,7 +61,6 @@ import io.netty.util.concurrent.GlobalEventExecutor;
* *
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
@io.netty.channel.ChannelHandler.Sharable @io.netty.channel.ChannelHandler.Sharable
public class OnvifDiscovery { public class OnvifDiscovery {
@ -110,7 +109,7 @@ public class OnvifDiscovery {
String temp = url; String temp = url;
BigDecimal onvifPort = new BigDecimal(80); BigDecimal onvifPort = new BigDecimal(80);
logger.info("Camera found at xAddr:{}", url); logger.info("Camera found at xAddr: {}", url);
int endIndex = temp.indexOf(" ");// Some xAddr have two urls with a space in between. int endIndex = temp.indexOf(" ");// Some xAddr have two urls with a space in between.
if (endIndex > 0) { if (endIndex > 0) {
temp = temp.substring(0, endIndex);// Use only the first url from now on. temp = temp.substring(0, endIndex);// Use only the first url from now on.
@ -139,7 +138,7 @@ public class OnvifDiscovery {
void processCameraReplys() { void processCameraReplys() {
for (DatagramPacket packet : listOfReplys) { for (DatagramPacket packet : listOfReplys) {
String xml = packet.content().toString(CharsetUtil.UTF_8); String xml = packet.content().toString(CharsetUtil.UTF_8);
logger.trace("Device replied to discovery with:{}", xml); logger.trace("Device replied to discovery with: {}", xml);
String xAddr = Helper.fetchXML(xml, "", "d:XAddrs>");// Foscam <wsdd:XAddrs> and all other brands <d:XAddrs> String xAddr = Helper.fetchXML(xml, "", "d:XAddrs>");// Foscam <wsdd:XAddrs> and all other brands <d:XAddrs>
if (!xAddr.isEmpty()) { if (!xAddr.isEmpty()) {
searchReply(xAddr, xml); searchReply(xAddr, xml);
@ -150,7 +149,7 @@ public class OnvifDiscovery {
} catch (IOException e) { } catch (IOException e) {
brand = "onvif"; brand = "onvif";
} }
logger.info("Possible {} camera found at:{}", brand, packet.sender().getHostString()); logger.debug("Possible {} camera found at: {}", brand, packet.sender().getHostString());
if ("reolink".equals(brand)) { if ("reolink".equals(brand)) {
ipCameraDiscoveryService.newCameraFound(brand, packet.sender().getHostString(), 8000); ipCameraDiscoveryService.newCameraFound(brand, packet.sender().getHostString(), 8000);
} else { } else {
@ -200,7 +199,7 @@ public class OnvifDiscovery {
response += temp; response += temp;
} }
reply.close(); reply.close();
logger.trace("Cameras Login page is:{}", response); logger.trace("Cameras Login page is: {}", response);
brand = checkForBrand(response); brand = checkForBrand(response);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
} finally { } finally {

View File

@ -22,7 +22,6 @@ import io.netty.handler.codec.http.LastHttpContent;
/** /**
* The {@link NettyRtspHandler} is used to decode RTSP traffic into message Strings. * The {@link NettyRtspHandler} is used to decode RTSP traffic into message Strings.
* *
*
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault

View File

@ -43,7 +43,6 @@ import io.netty.handler.timeout.IdleStateHandler;
* The {@link RtspConnection} is a WIP and not currently used, but will talk directly to RTSP and collect information * The {@link RtspConnection} is a WIP and not currently used, but will talk directly to RTSP and collect information
* about the camera and streams. * about the camera and streams.
* *
*
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault

View File

@ -109,7 +109,7 @@ public class CameraServlet extends IpCameraServlet {
Ffmpeg localFfmpeg = handler.ffmpegHLS; Ffmpeg localFfmpeg = handler.ffmpegHLS;
if (localFfmpeg == null) { if (localFfmpeg == null) {
handler.setupFfmpegFormat(FFmpegFormat.HLS); handler.setupFfmpegFormat(FFmpegFormat.HLS);
} else if (!localFfmpeg.getIsAlive()) { } else if (!localFfmpeg.isAlive()) {
localFfmpeg.startConverting(); localFfmpeg.startConverting();
} else { } else {
localFfmpeg.setKeepAlive(8); localFfmpeg.setKeepAlive(8);

View File

@ -63,7 +63,7 @@ public abstract class IpCameraServlet extends HttpServlet {
httpService.registerServlet("/ipcamera/" + handler.getThing().getUID().getId(), this, initParameters, httpService.registerServlet("/ipcamera/" + handler.getThing().getUID().getId(), this, initParameters,
httpService.createDefaultHttpContext()); httpService.createDefaultHttpContext());
} catch (Exception e) { } catch (Exception e) {
logger.warn("Registering servlet failed:{}", e.getMessage()); logger.warn("Registering servlet failed: {}", e.getMessage());
} }
} }

View File

@ -22,10 +22,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
* The {@link OpenStreams} Keeps track of all open mjpeg streams so the byte[] can be given to all FIFO buffers to allow * The {@link OpenStreams} Keeps track of all open mjpeg streams so the byte[] can be given to all FIFO buffers to allow
* 1 to many streams without needing to open more than 1 source stream. * 1 to many streams without needing to open more than 1 source stream.
* *
*
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
public class OpenStreams { public class OpenStreams {
private List<StreamOutput> openStreams = Collections.synchronizedList(new ArrayList<StreamOutput>()); private List<StreamOutput> openStreams = Collections.synchronizedList(new ArrayList<StreamOutput>());

View File

@ -28,7 +28,6 @@ import org.slf4j.LoggerFactory;
* *
* @author Matthew Skinner - Initial contribution * @author Matthew Skinner - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
public class StreamOutput { public class StreamOutput {
public final Logger logger = LoggerFactory.getLogger(getClass()); public final Logger logger = LoggerFactory.getLogger(getClass());
@ -79,7 +78,7 @@ public class StreamOutput {
try { try {
fifo.add(frame); fifo.add(frame);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
logger.debug("FIFO buffer has run out of space:{}", e.getMessage()); logger.debug("FIFO buffer has run out of space: {}", e.getMessage());
fifo.remove(); fifo.remove();
fifo.add(frame); fifo.add(frame);
} }