* Fix never ending WARN when HIK camera does not support alarm inputs.
* Streamline code.
* Update Instar support for 2k+ Generation.
* Fix alarm codes.
* Add CHANNEL_LAST_EVENT_DATA
Signed-off-by: Matthew Skinner <matt@pcmus.com>
|-|-|
| `ipAddress`| The IP address or host name of your camera. |
| `port`| This port will be used for HTTP calls for fetching the snapshot and any API calls. |
-| `onvifPort`| The port your camera uses for ONVIF connections. This is needed for PTZ movement, events, and the auto discovery of RTSP and snapshot URLs. |
+| `onvifPort`| The port your camera uses for ONVIF connections. This is needed for PTZ movement, events, and the auto discovery of RTSP and snapshot URLs. A value of 0 will prevent the binding from trying to connect to ONVIF. |
| `username`| Leave blank if your camera does not use login details. |
| `password`| Leave blank if your camera does not use login details. |
| `onvifMediaProfile`| 0 (default) is your cameras Mainstream and the numbers above 0 are the substreams. Any auto discovered URLs will use the streams that this indicates. You can always override the URLs should you wish to use something different for one of them. |
}
public void alarmTriggered(String alarm) {
- ipCameraHandler.logger.debug("Alarm has been triggered:{}", alarm);
- switch (alarm) {
- case "/instar?&active=1":// The motion area boxes 1-4
- case "/instar?&active=2":
- case "/instar?&active=3":
- case "/instar?&active=4":
+ // older cameras placed the & for the first query, whilst newer cameras do not.
+ // examples are /instar?&active=6 vs /instar?active=6&object=0
+ ipCameraHandler.setChannelState(CHANNEL_LAST_EVENT_DATA, new StringType(alarm));
+ String alarmCode = alarm.replaceAll(".+active=", "");
+ alarmCode = alarmCode.replaceAll("&.+", "");
+ String objectCode = alarm.replaceAll(".+object=", "");
+ switch (alarmCode) {
+ case "1":// The motion area boxes 1-4
+ case "2":
+ case "3":
+ case "4":
ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
break;
- case "/instar?&active=5":// PIR
+ case "5":// PIR
ipCameraHandler.motionDetected(CHANNEL_PIR_ALARM);
break;
- case "/instar?&active=6":// Audio Alarm
+ case "6":// Audio Alarm
ipCameraHandler.audioDetected();
break;
- case "/instar?&active=7":// Motion Area 1
- case "/instar?&active=8":// Motion Area 2
- case "/instar?&active=9":// Motion Area 3
- case "/instar?&active=10":// Motion Area 4
+ case "7":// Motion area 1 + PIR
+ case "8":// Motion area 2 + PIR
+ case "9":// Motion area 3 + PIR
+ case "10":// Motion area 4 + PIR
ipCameraHandler.motionDetected(CHANNEL_MOTION_ALARM);
+ ipCameraHandler.motionDetected(CHANNEL_PIR_ALARM);
break;
+ default:
+ ipCameraHandler.logger.debug("Unknown alarm code:{}", alarmCode);
+ }
+ if (!objectCode.isEmpty()) {
+ switch (objectCode) {
+ case "0":// no object
+ break;
+ case "1":// person/human
+ ipCameraHandler.motionDetected(CHANNEL_HUMAN_ALARM);
+ break;
+ case "2":// car/vehicles
+ ipCameraHandler.motionDetected(CHANNEL_CAR_ALARM);
+ break;
+ case "3":// animals
+ case "4":
+ case "5":
+ ipCameraHandler.motionDetected(CHANNEL_ANIMAL_ALARM);
+ break;
+ default:
+ ipCameraHandler.logger.debug("Unknown object detection code:{}", objectCode);
+ }
}
}
public static final String CHANNEL_ENABLE_PRIVACY_MODE = "enablePrivacyMode";
public static final String CHANNEL_CAR_ALARM = "carAlarm";
public static final String CHANNEL_HUMAN_ALARM = "humanAlarm";
+ public static final String CHANNEL_ANIMAL_ALARM = "animalAlarm";
}
// First run it should not have authenticate as null
// nonce is reused if authenticate is null so the NC needs to increment to allow this//
public void processAuth(String authenticate, String httpMethod, String requestURI, boolean reSend) {
- if (authenticate.contains("Basic realm=\"")) {
+ if (authenticate.contains("Basic realm=")) {
if (ipCameraHandler.useDigestAuth) {
// Possible downgrade authenticate attack avoided.
return;
}
return;
}
- if (!onvifCamera.isConnected()) {
+ if (cameraConfig.getOnvifPort() > 0 && !onvifCamera.isConnected()) {
logger.debug("About to connect to the IP Camera using the ONVIF PORT at IP:{}:{}", cameraConfig.getIp(),
cameraConfig.getOnvifPort());
onvifCamera.connect(thing.getThingTypeUID().getId().equals(ONVIF_THING));
}
noMotionDetected(CHANNEL_MOTION_ALARM);
noMotionDetected(CHANNEL_PIR_ALARM);
+ noMotionDetected(CHANNEL_HUMAN_ALARM);
+ noMotionDetected(CHANNEL_CAR_ALARM);
+ noMotionDetected(CHANNEL_ANIMAL_ALARM);
noAudioDetected();
break;
case HIKVISION_THING:
if (mjpegUri.isEmpty()) {
mjpegUri = "/mjpegstream.cgi?-chn=12";
}
+ // Newer Instar cameras use this to setup the Alarm Server
+ sendHttpGET(
+ "/param.cgi?cmd=setasaction&-server=1&enable=1&-interval=1&cmd=setasattr&-as_index=1&-as_server="
+ + hostIp + "&-as_port=" + SERVLET_PORT + "&-as_path=/ipcamera/"
+ + getThing().getUID().getId()
+ + "/instar&-as_ssl=0&-as_insecure=0&-as_mode=0&-as_activequery=1&-as_auth=0&-as_query1=0&-as_query2=0&-as_query3=0&-as_query4=0&-as_query5=0");
+ // Older Instar cameras use this to setup the Alarm Server
sendHttpGET(
"/param.cgi?cmd=setmdalarm&-aname=server2&-switch=on&-interval=1&cmd=setalarmserverattr&-as_index=3&-as_server="
+ hostIp + "&-as_port=" + SERVLET_PORT + "&-as_path=/ipcamera/"
+ getThing().getUID().getId()
- + "/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");
+ + "/instar&-as_ssl=0&-as_mode=1&-as_activequery=1&-as_auth=0&-as_query1=0&-as_query2=0&-as_query3=0&-as_query4=0&-as_query5=0");
break;
}
// for poll times 9 seconds and above don't display a warning about the Image channel.
private void tryConnecting() {
if (!thing.getThingTypeUID().getId().equals(GENERIC_THING)
- && !thing.getThingTypeUID().getId().equals(DOORBIRD_THING)) {
+ && !thing.getThingTypeUID().getId().equals(DOORBIRD_THING) && cameraConfig.getOnvifPort() > 0) {
onvifCamera = new OnvifConnection(this, cameraConfig.getIp() + ":" + cameraConfig.getOnvifPort(),
cameraConfig.getUser(), cameraConfig.getPassword());
onvifCamera.setSelectedMediaProfile(cameraConfig.getOnvifMediaProfile());
<channel id="lastMotionType" typeId="lastMotionType"/>
<channel id="ffmpegMotionControl" typeId="ffmpegMotionControl"/>
<channel id="ffmpegMotionAlarm" typeId="ffmpegMotionAlarm"/>
+ <channel id="carAlarm" typeId="carAlarm"/>
+ <channel id="humanAlarm" typeId="humanAlarm"/>
+ <channel id="animalAlarm" typeId="animalAlarm"/>
+ <channel id="lastEventData" typeId="lastEventData"/>
<channel id="enableMotionAlarm" typeId="enableMotionAlarm"/>
<channel id="motionAlarm" typeId="motionAlarm"/>
<channel id="externalMotion" typeId="externalMotion"/>
<state readOnly="true"/>
</channel-type>
+ <channel-type id="animalAlarm" advanced="true">
+ <item-type>Switch</item-type>
+ <label>Animal Alarm</label>
+ <description>An animal has triggered the object detection.</description>
+ <category>Alarm</category>
+ <state readOnly="true"/>
+ </channel-type>
+
<channel-type id="parkingAlarm" advanced="true">
<item-type>Switch</item-type>
<label>Parking Alarm</label>