this.nvrChannel = nvrChannel;
}
+ private void processEvent(String content) {
+ // some cameras use <dynChannelID> or <channelID> and NVRs use channel 0 to say all channels
+ if (content.contains("hannelID>" + nvrChannel) || content.contains("<channelID>0</channelID>")) {
+ final int debounce = 3;
+ String eventType = Helper.fetchXML(content, "", "<eventType>");
+ switch (eventType) {
+ case "videoloss":
+ if (content.contains("<eventState>inactive</eventState>")) {
+ if (vmdCount > 1) {
+ vmdCount = 1;
+ }
+ countDown();
+ countDown();
+ }
+ break;
+ case "PIR":
+ ipCameraHandler.motionDetected(CHANNEL_PIR_ALARM);
+ pirCount = debounce;
+ break;
+ case "attendedBaggage":
+ ipCameraHandler.setChannelState(CHANNEL_ITEM_TAKEN, OnOffType.ON);
+ takenCount = debounce;
+ break;
+ case "unattendedBaggage":
+ ipCameraHandler.setChannelState(CHANNEL_ITEM_LEFT, OnOffType.ON);
+ leftCount = debounce;
+ break;
+ case "facedetection":
+ ipCameraHandler.setChannelState(CHANNEL_FACE_DETECTED, OnOffType.ON);
+ faceCount = debounce;
+ break;
+ case "VMD":
+ ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
+ vmdCount = debounce;
+ break;
+ case "fielddetection":
+ ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM);
+ fieldCount = debounce;
+ break;
+ case "linedetection":
+ ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM);
+ lineCount = debounce;
+ break;
+ default:
+ logger.debug("Unrecognised Hikvision eventType={}", eventType);
+ }
+ }
+ countDown();
+ }
+
// This handles the incoming http replies back from the camera.
@Override
public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object msg) throws Exception {
return;
}
try {
- int debounce = 3;
String content = msg.toString();
logger.trace("HTTP Result back from camera is \t:{}:", content);
- if (content.contains("--boundary")) {// Alarm checking goes in here//
- if (content.contains("<EventNotificationAlert version=\"")) {
- if (content.contains("hannelID>" + nvrChannel + "</")) {// some camera use c or <dynChannelID>
- if (content.contains("<eventType>linedetection</eventType>")) {
- ipCameraHandler.motionDetected(CHANNEL_LINE_CROSSING_ALARM);
- lineCount = debounce;
- }
- if (content.contains("<eventType>fielddetection</eventType>")) {
- ipCameraHandler.motionDetected(CHANNEL_FIELD_DETECTION_ALARM);
- fieldCount = debounce;
- }
- if (content.contains("<eventType>VMD</eventType>")) {
- ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
- vmdCount = debounce;
- }
- if (content.contains("<eventType>facedetection</eventType>")) {
- ipCameraHandler.setChannelState(CHANNEL_FACE_DETECTED, OnOffType.ON);
- faceCount = debounce;
- }
- if (content.contains("<eventType>unattendedBaggage</eventType>")) {
- ipCameraHandler.setChannelState(CHANNEL_ITEM_LEFT, OnOffType.ON);
- leftCount = debounce;
- }
- if (content.contains("<eventType>attendedBaggage</eventType>")) {
- ipCameraHandler.setChannelState(CHANNEL_ITEM_TAKEN, OnOffType.ON);
- takenCount = debounce;
- }
- if (content.contains("<eventType>PIR</eventType>")) {
- ipCameraHandler.motionDetected(CHANNEL_PIR_ALARM);
- pirCount = debounce;
- }
- if (content.contains("<eventType>videoloss</eventType>\r\n<eventState>inactive</eventState>")) {
- if (vmdCount > 1) {
- vmdCount = 1;
- }
- countDown();
- countDown();
- }
- } else if (content.contains("<channelID>0</channelID>")) {// NVR uses channel 0 to say all
- // channels
- if (content.contains("<eventType>videoloss</eventType>\r\n<eventState>inactive</eventState>")) {
- if (vmdCount > 1) {
- vmdCount = 1;
- }
- countDown();
- countDown();
- }
- }
- countDown();
- }
+ if (content.startsWith("--boundary")) {// Alarm checking goes in here//
+ processEvent(content);
} else {
String replyElement = Helper.fetchXML(content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<");
switch (replyElement) {
}
break;
default:
- if (content.contains("<EventNotificationAlert")) {
- if (content.contains("hannelID>" + nvrChannel + "</")
- || content.contains("<channelID>0</channelID>")) {// some camera use c or
- // <dynChannelID>
- if (content.contains(
- "<eventType>videoloss</eventType>\r\n<eventState>inactive</eventState>")) {
- if (vmdCount > 1) {
- vmdCount = 1;
- }
- countDown();
- countDown();
- }
- countDown();
- }
- } else {
- logger.debug("Unhandled reply-{}.", content);
- }
+ logger.debug("Unhandled reply-{}.", content);
break;
}
}
private byte[] incomingJpeg = new byte[0];
private String incomingMessage = "";
private String contentType = "empty";
+ private String boundary = "";
private Object reply = new Object();
private String requestUrl = "";
private boolean closeConnection = true;
firstStreamedMsg = msg;
streamToGroup(firstStreamedMsg, mjpegChannelGroup, true);
}
+ } else {
+ boundary = Helper.searchString(contentType, "boundary=");
}
} else if (contentType.contains("image/jp")) {
if (bytesToRecieve == 0) {
}
// Alarm Streams never have a LastHttpContent as they always stay open//
else if (contentType.contains("multipart")) {
- if (bytesAlreadyRecieved != 0) {
- reply = incomingMessage;
- incomingMessage = "";
- bytesToRecieve = 0;
- bytesAlreadyRecieved = 0;
+ int beginIndex, endIndex;
+ if (bytesToRecieve == 0) {
+ beginIndex = incomingMessage.indexOf("Content-Length:");
+ if (beginIndex != -1) {
+ endIndex = incomingMessage.indexOf("\r\n", beginIndex);
+ if (endIndex != -1) {
+ bytesToRecieve = Integer.parseInt(
+ incomingMessage.substring(beginIndex + 15, endIndex).strip());
+ }
+ }
+ }
+ // --boundary and headers are not included in the Content-Length value
+ if (bytesAlreadyRecieved > bytesToRecieve) {
+ // Check if message has a second --boundary
+ endIndex = incomingMessage.indexOf("--" + boundary, bytesToRecieve);
+ if (endIndex == -1) {
+ reply = incomingMessage;
+ incomingMessage = "";
+ bytesToRecieve = 0;
+ bytesAlreadyRecieved = 0;
+ } else {
+ reply = incomingMessage.substring(0, endIndex);
+ incomingMessage = incomingMessage.substring(endIndex, incomingMessage.length());
+ bytesToRecieve = 0;// Triggers search next time for Content-Length:
+ bytesAlreadyRecieved = incomingMessage.length() - endIndex;
+ }
super.channelRead(ctx, reply);
}
}
updateState(channelToUpdate, valueOf);
}
- void bringCameraOnline() {
+ private void bringCameraOnline() {
isOnline = true;
updateStatus(ThingStatus.ONLINE);
groupTracker.listOfOnlineCameraHandlers.add(this);
localFuture.cancel(false);
}
- switch (thing.getThingTypeUID().getId()) {
- case HIKVISION_THING:
- sendHttpGET("/ISAPI/Smart/AudioDetection/channels/" + cameraConfig.getNvrChannel() + "01");
- sendHttpGET("/ISAPI/Smart/LineDetection/" + cameraConfig.getNvrChannel() + "01");
- sendHttpGET("/ISAPI/Smart/FieldDetection/" + cameraConfig.getNvrChannel() + "01");
- sendHttpGET(
- "/ISAPI/System/Video/inputs/channels/" + cameraConfig.getNvrChannel() + "01/motionDetection");
- sendHttpGET("/ISAPI/System/Video/inputs/channels/" + cameraConfig.getNvrChannel() + "/overlays/text/1");
- sendHttpGET("/ISAPI/System/IO/inputs/" + cameraConfig.getNvrChannel());
- sendHttpGET("/ISAPI/System/IO/inputs/" + cameraConfig.getNvrChannel());
- break;
- }
-
if (cameraConfig.getGifPreroll() > 0 || cameraConfig.getUpdateImageWhen().contains("1")) {
snapshotPolling = true;
snapshotJob = threadPool.scheduleWithFixedDelay(this::snapshotRunnable, 1000, cameraConfig.getPollTime(),