Update openhab controls by asking camera for states. (#17639)

Signed-off-by: Matthew Skinner <matt@pcmus.com>
Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Matthew Skinner 2024-10-28 20:24:26 +11:00 committed by Ciprian Pascu
parent f13c5c5072
commit d20144d932
4 changed files with 77 additions and 14 deletions

View File

@ -106,6 +106,10 @@ public class CameraConfig {
return alarmInputUrl; return alarmInputUrl;
} }
public void setAlarmInputUrl(String url) {
alarmInputUrl = url;
}
public String getCustomAudioAlarmUrl() { public String getCustomAudioAlarmUrl() {
return customAudioAlarmUrl; return customAudioAlarmUrl;
} }

View File

@ -131,6 +131,14 @@ public class ReolinkHandler extends ChannelDuplexHandler {
removeChannels.add(channel); removeChannels.add(channel);
} }
} }
if (getAbilityResponse[0].value.ability.abilityChn[0].supportAiTrackClassify == null
|| getAbilityResponse[0].value.ability.abilityChn[0].supportAiTrackClassify.permit == 0) {
ipCameraHandler.logger.debug("Camera has no AiTrackClassify support.");
channel = ipCameraHandler.getThing().getChannel(CHANNEL_AUTO_TRACKING);
if (channel != null) {
removeChannels.add(channel);
}
}
if (getAbilityResponse[0].value.ability.abilityChn[0].supportAiPeople == null if (getAbilityResponse[0].value.ability.abilityChn[0].supportAiPeople == null
|| getAbilityResponse[0].value.ability.abilityChn[0].supportAiPeople.permit == 0) { || getAbilityResponse[0].value.ability.abilityChn[0].supportAiPeople.permit == 0) {
ipCameraHandler.logger.debug("Camera has no AiPeople support."); ipCameraHandler.logger.debug("Camera has no AiPeople support.");
@ -243,7 +251,7 @@ public class ReolinkHandler extends ChannelDuplexHandler {
} }
break; break;
case "/api.cgi?cmd=GetIrLights": case "/api.cgi?cmd=GetIrLights":
if (content.contains("\"state\" : 0")) { if (content.contains("\"state\" : \"Off\"")) {
ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF); ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF);
} else { } else {
ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.ON); ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.ON);
@ -266,17 +274,24 @@ public class ReolinkHandler extends ChannelDuplexHandler {
case "/api.cgi?cmd=GetEmail": case "/api.cgi?cmd=GetEmail":
case "/api.cgi?cmd=GetEmailV20": case "/api.cgi?cmd=GetEmailV20":
if (content.contains("\"enable\" : 0")) { if (content.contains("\"enable\" : 0")) {
ipCameraHandler.setChannelState(CHANNEL_MOTION_ALARM, OnOffType.OFF); ipCameraHandler.setChannelState(CHANNEL_ENABLE_EMAIL, OnOffType.OFF);
} else { } else {
ipCameraHandler.setChannelState(CHANNEL_MOTION_ALARM, OnOffType.ON); ipCameraHandler.setChannelState(CHANNEL_ENABLE_EMAIL, OnOffType.ON);
} }
break; break;
case "/api.cgi?cmd=GetPush": case "/api.cgi?cmd=GetPush":
case "/api.cgi?cmd=GetPushV20": case "/api.cgi?cmd=GetPushV20":
if (content.contains("\"enable\" : 0")) { if (content.contains("\"enable\" : 0")) {
ipCameraHandler.setChannelState(CHANNEL_MOTION_ALARM, OnOffType.OFF); ipCameraHandler.setChannelState(CHANNEL_ENABLE_PUSH, OnOffType.OFF);
} else { } else {
ipCameraHandler.setChannelState(CHANNEL_MOTION_ALARM, OnOffType.ON); ipCameraHandler.setChannelState(CHANNEL_ENABLE_PUSH, OnOffType.ON);
}
break;
case "/api.cgi?cmd=GetFtpV20":
if (content.contains("\"enable\" : 0")) {
ipCameraHandler.setChannelState(CHANNEL_ENABLE_FTP, OnOffType.OFF);
} else {
ipCameraHandler.setChannelState(CHANNEL_ENABLE_FTP, OnOffType.ON);
} }
break; break;
case "/api.cgi?cmd=GetWhiteLed": case "/api.cgi?cmd=GetWhiteLed":
@ -288,8 +303,22 @@ public class ReolinkHandler extends ChannelDuplexHandler {
break; break;
case "/cgi-bin/api.cgi?cmd=Snap": case "/cgi-bin/api.cgi?cmd=Snap":
break; break;
case "/api.cgi?cmd=GetAiCfg":
if (content.contains("\"bSmartTrack\" : 0")) {
ipCameraHandler.setChannelState(CHANNEL_AUTO_TRACKING, OnOffType.OFF);
} else {
ipCameraHandler.setChannelState(CHANNEL_AUTO_TRACKING, OnOffType.ON);
}
break;
case "/api.cgi?cmd=GetRecV20":
if (content.contains("\"enable\" : 0")) {
ipCameraHandler.setChannelState(CHANNEL_ENABLE_RECORDINGS, OnOffType.OFF);
} else {
ipCameraHandler.setChannelState(CHANNEL_ENABLE_RECORDINGS, OnOffType.ON);
}
break;
default: default:
if (!cutDownURL.contains("cmd=Set")) {// ignore the responses from all Setxxxxx commands if (!cutDownURL.startsWith("/cgi-bin/api.cgi?cmd=Set")) {// ignore responses from all Setxx commands
ipCameraHandler.logger.warn( ipCameraHandler.logger.warn(
"URL {} is not handled currently by the binding, please report this message", "URL {} is not handled currently by the binding, please report this message",
cutDownURL); cutDownURL);
@ -311,11 +340,13 @@ public class ReolinkHandler extends ChannelDuplexHandler {
break; break;
case CHANNEL_ENABLE_AUDIO_ALARM: case CHANNEL_ENABLE_AUDIO_ALARM:
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetAudioAlarmV20" + ipCameraHandler.reolinkAuth, ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetAudioAlarmV20" + ipCameraHandler.reolinkAuth,
"[{ \"cmd\":\"GetAudioAlarmV20\", \"action\":1, \"param\":{ \"channel\": 0}}]"); "[{\"cmd\": \"GetAudioAlarmV20\", \"action\": 1,\"param\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + "}}]");
break; break;
case CHANNEL_AUTO_LED: case CHANNEL_AUTO_LED:
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetIrLights" + ipCameraHandler.reolinkAuth, ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetIrLights" + ipCameraHandler.reolinkAuth,
"[{ \"cmd\":\"GetIrLights\"}]"); "[{\"cmd\": \"GetIrLights\", \"action\": 1,\"param\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + "}}]");
break; break;
case CHANNEL_AUTO_WHITE_LED: case CHANNEL_AUTO_WHITE_LED:
case CHANNEL_WHITE_LED: case CHANNEL_WHITE_LED:
@ -325,12 +356,31 @@ public class ReolinkHandler extends ChannelDuplexHandler {
break; break;
case CHANNEL_ENABLE_EMAIL: case CHANNEL_ENABLE_EMAIL:
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetEmailV20" + ipCameraHandler.reolinkAuth, ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetEmailV20" + ipCameraHandler.reolinkAuth,
"[{ \"cmd\":\"GetEmailV20\"}]"); "[{\"cmd\": \"GetEmailV20\", \"action\": 1,\"param\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + "}}]");
break; break;
case CHANNEL_ENABLE_PUSH: case CHANNEL_ENABLE_PUSH:
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetPushV20" + ipCameraHandler.reolinkAuth, ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetPushV20" + ipCameraHandler.reolinkAuth,
"[{ \"cmd\":\"GetPush\"}]"); "[{\"cmd\": \"GetPushV20\", \"action\": 1,\"param\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + "}}]");
break; break;
case CHANNEL_ENABLE_FTP:
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetFtpV20" + ipCameraHandler.reolinkAuth,
"[{\"cmd\": \"GetFtpV20\", \"action\": 1,\"param\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + "}}]");
break;
case CHANNEL_AUTO_TRACKING:
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetAiCfg" + ipCameraHandler.reolinkAuth,
"[{\"cmd\": \"GetAiCfg\", \"action\": 1,\"param\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + "}}]");
break;
case CHANNEL_ENABLE_RECORDINGS:
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=GetRecV20" + ipCameraHandler.reolinkAuth,
"[{\"cmd\": \"GetRecV20\", \"action\": 1,\"param\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + "}}]");
default:
ipCameraHandler.logger.trace("REFRESH command is not implemented for channel:{}", channelUID);
} }
return; return;
} // end of "REFRESH" } // end of "REFRESH"
@ -451,12 +501,11 @@ public class ReolinkHandler extends ChannelDuplexHandler {
ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF); ipCameraHandler.setChannelState(CHANNEL_AUTO_LED, OnOffType.OFF);
if (OnOffType.OFF.equals(command) || PercentType.ZERO.equals(command)) { if (OnOffType.OFF.equals(command) || PercentType.ZERO.equals(command)) {
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=SetIrLights" + ipCameraHandler.reolinkAuth, ipCameraHandler.sendHttpPOST("/api.cgi?cmd=SetIrLights" + ipCameraHandler.reolinkAuth,
"[{\"cmd\": \"SetIrLights\",\"action\": 0,\"param\": {\"IrLights\": {\"channel\": " "[{\"cmd\": \"SetIrLights\", \"value\" : { \"IrLights\" : { \"state\" : \"Off\" } } } ]");
+ ipCameraHandler.cameraConfig.getNvrChannel() + ",\"state\": \"Off\"}}}]");
} else if (OnOffType.ON.equals(command) || command instanceof PercentType) { } else if (OnOffType.ON.equals(command) || command instanceof PercentType) {
ipCameraHandler.sendHttpPOST("/api.cgi?cmd=SetIrLights" + ipCameraHandler.reolinkAuth, ipCameraHandler.sendHttpPOST("/api.cgi?cmd=SetIrLights" + ipCameraHandler.reolinkAuth,
"[{\"cmd\": \"SetIrLights\",\"action\": 0,\"param\": {\"IrLights\": {\"channel\": " "[{\"cmd\": \"SetIrLights\", \"value\" : {\"IrLights\": {\"channel\": "
+ ipCameraHandler.cameraConfig.getNvrChannel() + ",\"state\": \"On\"}}}]"); + ipCameraHandler.cameraConfig.getNvrChannel() + ",\"state\": \"Auto\"}}}]");
} else { } else {
ipCameraHandler.logger.warn("Unsupported command sent to enableLED channel"); ipCameraHandler.logger.warn("Unsupported command sent to enableLED channel");
} }

View File

@ -58,6 +58,7 @@ public class ReolinkState {
public AbilityKey supportAiPeople = new AbilityKey(); public AbilityKey supportAiPeople = new AbilityKey();
public AbilityKey supportAiVehicle = new AbilityKey(); public AbilityKey supportAiVehicle = new AbilityKey();
public AbilityKey supportAiDogCat = new AbilityKey(); public AbilityKey supportAiDogCat = new AbilityKey();
public AbilityKey supportAiTrackClassify = new AbilityKey();
} }
public AbilityChn[] abilityChn = new AbilityChn[1]; public AbilityChn[] abilityChn = new AbilityChn[1];

View File

@ -1398,6 +1398,11 @@ public class IpCameraHandler extends BaseThingHandler {
logger.debug("Token thread for REOLINK was stopped, restarting it now."); logger.debug("Token thread for REOLINK was stopped, restarting it now.");
authenticationJob = threadPool.scheduleWithFixedDelay(this::getReolinkToken, 0, 45, TimeUnit.MINUTES); authenticationJob = threadPool.scheduleWithFixedDelay(this::getReolinkToken, 0, 45, TimeUnit.MINUTES);
} }
// Ask camera and update openHAB controls to match cameras settings
List<org.openhab.core.thing.Channel> channels = thing.getChannels();
for (org.openhab.core.thing.Channel channel : channels) {
this.handleCommand(channel.getUID(), RefreshType.REFRESH);
}
} }
void snapshotIsFfmpeg() { void snapshotIsFfmpeg() {
@ -1758,6 +1763,10 @@ public class IpCameraHandler extends BaseThingHandler {
mjpegUri = "rtsp://" + cameraConfig.getIp() + ":554/h264Preview_0" mjpegUri = "rtsp://" + cameraConfig.getIp() + ":554/h264Preview_0"
+ (cameraConfig.getNvrChannel() + 1) + "_sub"; + (cameraConfig.getNvrChannel() + 1) + "_sub";
} }
if (cameraConfig.getAlarmInputUrl().isEmpty()) {
cameraConfig.setAlarmInputUrl("rtsp://" + cameraConfig.getIp() + ":554/h264Preview_0"
+ (cameraConfig.getNvrChannel() + 1) + "_sub");
}
break; break;
} }
// for poll times 9 seconds and above don't display a warning about the Image channel. // for poll times 9 seconds and above don't display a warning about the Image channel.