[zoneminder] Add support for setting the server run state (#14906)

* Add support for server run states

Signed-off-by: Mark Hilbush <mark@hilbush.com>
pull/14915/head
Mark Hilbush 2023-04-30 09:10:54 -04:00 committed by GitHub
parent 0437595678
commit 49d2ecc4c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 163 additions and 0 deletions

View File

@ -77,6 +77,7 @@ The following configuration parameters are available on the Monitor thing:
| imageUrl | String | Image URL for monitor id specified by imageMonitorId. Channel is UNDEF if the monitor id is not set, or if an OFF command is sent to the imageMonitorId channel. | | imageUrl | String | Image URL for monitor id specified by imageMonitorId. Channel is UNDEF if the monitor id is not set, or if an OFF command is sent to the imageMonitorId channel. |
| videoMonitorId | String | Monitor ID to use for selecting a video URL. Also, sending an OFF command to this channel will reset the monitor id and url to UNDEF. | | videoMonitorId | String | Monitor ID to use for selecting a video URL. Also, sending an OFF command to this channel will reset the monitor id and url to UNDEF. |
| videoUrl | String | Video URL for monitor id specified by videoMonitorId. Channel is UNDEF if the monitor id is not set, or if an OFF command is sent to the videoMonitorId channel. | | videoUrl | String | Video URL for monitor id specified by videoMonitorId. Channel is UNDEF if the monitor id is not set, or if an OFF command is sent to the videoMonitorId channel. |
| runState | String | Set the run state for the ZoneMinder server |
### Monitor Thing ### Monitor Thing
@ -171,6 +172,7 @@ String ZmServer_ImageMonitorId "Image Monitor Id [%s]" { channel="zoneminder:ser
String ZmServer_ImageUrl "Image Url [%s]" { channel="zoneminder:server:server:imageUrl" } String ZmServer_ImageUrl "Image Url [%s]" { channel="zoneminder:server:server:imageUrl" }
String ZmServer_VideoMonitorId "Video Monitor Id [%s]" { channel="zm:server:server:videoMonitorId" } String ZmServer_VideoMonitorId "Video Monitor Id [%s]" { channel="zm:server:server:videoMonitorId" }
String ZmServer_VideoUrl "Video Url [%s]" { channel="zoneminder:server:server:videoUrl" } String ZmServer_VideoUrl "Video Url [%s]" { channel="zoneminder:server:server:videoUrl" }
String ZmServer_RunState "Run State [%s]" { channel="zoneminder:server:server:runState" }
// Monitor // Monitor
String ZM_Monitor1_Id "Monitor Id [%s]" { channel="zoneminder:monitor:1:id" } String ZM_Monitor1_Id "Monitor Id [%s]" { channel="zoneminder:monitor:1:id" }

View File

@ -67,6 +67,7 @@ public class ZmBindingConstants {
public static final String DEFAULT_URL_PATH = "/zm"; public static final String DEFAULT_URL_PATH = "/zm";
// List of all channel ids // List of all channel ids
public static final String CHANNEL_RUN_STATE = "runState";
public static final String CHANNEL_IMAGE_MONITOR_ID = "imageMonitorId"; public static final String CHANNEL_IMAGE_MONITOR_ID = "imageMonitorId";
public static final String CHANNEL_VIDEO_MONITOR_ID = "videoMonitorId"; public static final String CHANNEL_VIDEO_MONITOR_ID = "videoMonitorId";
public static final String CHANNEL_ID = "id"; public static final String CHANNEL_ID = "id";

View File

@ -0,0 +1,55 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.zoneminder.internal.dto;
import com.google.gson.annotations.SerializedName;
/**
* The {@link RunStateDTO} contains a run state.
*
* @author Mark Hilbush - Initial contribution
*/
public class RunStateDTO extends AbstractResponseDTO {
/**
* A run state
*/
@SerializedName("State")
public RunState runState;
public class RunState {
/**
* ID of run state, typically "1", "2", etc.
*/
@SerializedName("Id")
public String id;
/**
* Name of run state
*/
@SerializedName("Name")
public String name;
/**
* Definition of the run state
*/
@SerializedName("Definition")
public String definition;
/**
* "1" if run state is active; "0" if not active
*/
@SerializedName("IsActive")
public String isActive;
}
}

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.zoneminder.internal.dto;
import java.util.List;
import com.google.gson.annotations.SerializedName;
/**
* The {@link RunStatesDTO} contains the list of run states.
*
* @author Mark Hilbush - Initial contribution
*/
public class RunStatesDTO extends AbstractResponseDTO {
/**
* List of run states
*/
@SerializedName("states")
public List<RunStateDTO> runStatesList;
}

View File

@ -16,6 +16,8 @@ import static org.openhab.binding.zoneminder.internal.ZmBindingConstants.*;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -48,6 +50,9 @@ import org.openhab.binding.zoneminder.internal.dto.MonitorItemDTO;
import org.openhab.binding.zoneminder.internal.dto.MonitorStateDTO; import org.openhab.binding.zoneminder.internal.dto.MonitorStateDTO;
import org.openhab.binding.zoneminder.internal.dto.MonitorStatusDTO; import org.openhab.binding.zoneminder.internal.dto.MonitorStatusDTO;
import org.openhab.binding.zoneminder.internal.dto.MonitorsDTO; import org.openhab.binding.zoneminder.internal.dto.MonitorsDTO;
import org.openhab.binding.zoneminder.internal.dto.RunStateDTO;
import org.openhab.binding.zoneminder.internal.dto.RunStateDTO.RunState;
import org.openhab.binding.zoneminder.internal.dto.RunStatesDTO;
import org.openhab.binding.zoneminder.internal.dto.VersionDTO; import org.openhab.binding.zoneminder.internal.dto.VersionDTO;
import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.io.net.http.HttpUtil;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@ -186,6 +191,11 @@ public class ZmBridgeHandler extends BaseBridgeHandler {
case CHANNEL_VIDEO_MONITOR_ID: case CHANNEL_VIDEO_MONITOR_ID:
handleMonitorIdCommand(command, CHANNEL_VIDEO_MONITOR_ID, CHANNEL_VIDEO_URL, STREAM_VIDEO); handleMonitorIdCommand(command, CHANNEL_VIDEO_MONITOR_ID, CHANNEL_VIDEO_URL, STREAM_VIDEO);
break; break;
case CHANNEL_RUN_STATE:
if (command instanceof StringType) {
changeRunState(command);
}
break;
} }
} }
@ -204,6 +214,12 @@ public class ZmBridgeHandler extends BaseBridgeHandler {
} }
} }
private void changeRunState(Command command) {
logger.debug("Bridge: Change run state to {}", command);
executeGet(buildUrl(String.format("/api/states/change/%s.json",
URLEncoder.encode(command.toString(), Charset.defaultCharset()))));
}
@Override @Override
public Collection<Class<? extends ThingHandlerService>> getServices() { public Collection<Class<? extends ThingHandlerService>> getServices() {
return Collections.singleton(MonitorDiscoveryService.class); return Collections.singleton(MonitorDiscoveryService.class);
@ -332,6 +348,7 @@ public class ZmBridgeHandler extends BaseBridgeHandler {
m.setLastEvent(getLastEvent(m.getId())); m.setLastEvent(getLastEvent(m.getId()));
} }
} }
updateRunStates();
} }
} catch (JsonSyntaxException e) { } catch (JsonSyntaxException e) {
logger.debug("Bridge: JsonSyntaxException: {}", e.getMessage(), e); logger.debug("Bridge: JsonSyntaxException: {}", e.getMessage(), e);
@ -390,6 +407,32 @@ public class ZmBridgeHandler extends BaseBridgeHandler {
return null; return null;
} }
private void updateRunStates() {
if (!zmAuth.isAuthorized() || !isLinked(CHANNEL_RUN_STATE)) {
return;
}
try {
String response = executeGet(buildUrl("/api/states.json"));
RunStatesDTO runStates = GSON.fromJson(response, RunStatesDTO.class);
if (runStates != null) {
List<StateOption> options = new ArrayList<>();
for (RunStateDTO runState : runStates.runStatesList) {
RunState state = runState.runState;
logger.debug("Found runstate: id={}, name={}, desc={}, isActive={}", state.id, state.name,
state.definition, state.isActive);
options.add(new StateOption(state.name, state.name));
if ("1".equals(state.isActive)) {
updateState(CHANNEL_RUN_STATE, new StringType(state.name));
}
}
stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_RUN_STATE),
options);
}
} catch (JsonSyntaxException e) {
logger.debug("Bridge: JsonSyntaxException: {}", e.getMessage(), e);
}
}
private @Nullable VersionDTO getVersion() { private @Nullable VersionDTO getVersion() {
if (!zmAuth.isAuthorized()) { if (!zmAuth.isAuthorized()) {
return null; return null;

View File

@ -99,6 +99,8 @@ channel-type.zoneminder.image.label = Image
channel-type.zoneminder.image.description = A single snapshot image channel-type.zoneminder.image.description = A single snapshot image
channel-type.zoneminder.name.label = Name channel-type.zoneminder.name.label = Name
channel-type.zoneminder.name.description = Monitor name channel-type.zoneminder.name.description = Monitor name
channel-type.zoneminder.runState.label = Run State
channel-type.zoneminder.runState.description = The currently executing run state
channel-type.zoneminder.state.label = State channel-type.zoneminder.state.label = State
channel-type.zoneminder.state.description = Current monitor state channel-type.zoneminder.state.description = Current monitor state
channel-type.zoneminder.state.state.option.UNKNOWN = UNKNOWN channel-type.zoneminder.state.state.option.UNKNOWN = UNKNOWN

View File

@ -7,6 +7,7 @@
<bridge-type id="server"> <bridge-type id="server">
<label>ZoneMinder Server</label> <label>ZoneMinder Server</label>
<description>Represents a ZoneMinder server</description> <description>Represents a ZoneMinder server</description>
<channels> <channels>
<channel id="imageMonitorId" typeId="id"> <channel id="imageMonitorId" typeId="id">
<label>Image Monitor Id</label> <label>Image Monitor Id</label>
@ -22,7 +23,13 @@
<channel id="videoUrl" typeId="url"> <channel id="videoUrl" typeId="url">
<label>Video URL</label> <label>Video URL</label>
</channel> </channel>
<channel id="runState" typeId="runState"/>
</channels> </channels>
<properties>
<property name="thingTypeVersion">1</property>
</properties>
<config-description-ref uri="thing-type:zoneminder:server"/> <config-description-ref uri="thing-type:zoneminder:server"/>
</bridge-type> </bridge-type>
@ -216,5 +223,11 @@
<description>Length of the event in seconds</description> <description>Length of the event in seconds</description>
<state readOnly="true" pattern="%.2f %unit%"></state> <state readOnly="true" pattern="%.2f %unit%"></state>
</channel-type> </channel-type>
<channel-type id="runState">
<item-type>String</item-type>
<label>Run State</label>
<description>The currently executing run state</description>
<state readOnly="false" pattern="%s"></state>
</channel-type>
</thing:thing-descriptions> </thing:thing-descriptions>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
<thing-type uid="zoneminder:server">
<instruction-set targetVersion="1">
<add-channel id="runState">
<type>zoneminder:runState</type>
</add-channel>
</instruction-set>
</thing-type>
</update:update-descriptions>