2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.unifi.internal.handler;
15 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_ENABLE_PARAMETER_MODE;
16 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_ENABLE_PARAMETER_MODE_AUTO;
17 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_ENABLE_PARAMETER_MODE_OFF;
18 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_ONLINE;
19 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_CMD;
20 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_CMD_POWER_CYCLE;
21 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_CURRENT;
22 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_ENABLE;
23 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_MODE;
24 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_POWER;
25 import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_VOLTAGE;
26 import static org.openhab.core.library.unit.MetricPrefix.MILLI;
28 import java.util.HashMap;
31 import javax.measure.quantity.ElectricCurrent;
32 import javax.measure.quantity.ElectricPotential;
33 import javax.measure.quantity.Power;
35 import org.eclipse.jdt.annotation.NonNullByDefault;
36 import org.eclipse.jdt.annotation.Nullable;
37 import org.openhab.binding.unifi.internal.UniFiPoePortThingConfig;
38 import org.openhab.binding.unifi.internal.api.UniFiController;
39 import org.openhab.binding.unifi.internal.api.UniFiException;
40 import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
41 import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverride;
42 import org.openhab.binding.unifi.internal.api.dto.UniFiDevice;
43 import org.openhab.binding.unifi.internal.api.dto.UniFiPortTable;
44 import org.openhab.core.library.types.OnOffType;
45 import org.openhab.core.library.types.QuantityType;
46 import org.openhab.core.library.types.StringType;
47 import org.openhab.core.library.unit.Units;
48 import org.openhab.core.thing.ChannelUID;
49 import org.openhab.core.thing.Thing;
50 import org.openhab.core.thing.ThingStatus;
51 import org.openhab.core.thing.ThingStatusDetail;
52 import org.openhab.core.types.Command;
53 import org.openhab.core.types.State;
54 import org.openhab.core.types.UnDefType;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
59 * A Power Over Ethernet (PoE) port on a UniFi switch.
61 * @author Hilbrand Bouwkamp - Initial contribution
64 public class UniFiPoePortThingHandler
65 extends UniFiBaseThingHandler<Map<Integer, UniFiPortTable>, UniFiPoePortThingConfig> {
67 private final Logger logger = LoggerFactory.getLogger(UniFiPoePortThingHandler.class);
69 private UniFiPoePortThingConfig config = new UniFiPoePortThingConfig();
70 private String poeEnableMode = "";
72 public UniFiPoePortThingHandler(final Thing thing) {
77 protected boolean initialize(final UniFiPoePortThingConfig config) {
79 if (!config.isValid()) {
80 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
81 "@text/error.thing.poe.offline.configuration_error");
84 final String channelConfigPoeEnableMode = (String) getThing().getChannel(CHANNEL_PORT_POE_ENABLE)
85 .getConfiguration().get(CHANNEL_ENABLE_PARAMETER_MODE);
86 poeEnableMode = channelConfigPoeEnableMode.isBlank() ? CHANNEL_ENABLE_PARAMETER_MODE_AUTO
87 : channelConfigPoeEnableMode;
92 protected @Nullable Map<Integer, UniFiPortTable> getEntity(final UniFiControllerCache cache) {
93 return cache.getSwitchPorts(config.getMacAddress());
97 protected State getChannelState(final Map<Integer, UniFiPortTable> ports, final String channelId) {
98 final UniFiPortTable port = getPort(ports);
101 logger.debug("No PoE port for thing '{}' could be found in the data. Refresh ignored.",
102 getThing().getUID());
103 return UnDefType.NULL;
109 state = OnOffType.from(port.isUp());
111 case CHANNEL_PORT_POE_ENABLE:
112 state = OnOffType.from(port.isPoeEnabled());
114 case CHANNEL_PORT_POE_MODE:
115 state = StringType.valueOf(port.getPoeMode());
117 case CHANNEL_PORT_POE_POWER:
118 state = new QuantityType<Power>(Double.valueOf(port.getPoePower()), Units.WATT);
120 case CHANNEL_PORT_POE_VOLTAGE:
121 state = new QuantityType<ElectricPotential>(Double.valueOf(port.getPoeVoltage()), Units.VOLT);
123 case CHANNEL_PORT_POE_CURRENT:
124 state = new QuantityType<ElectricCurrent>(Double.valueOf(port.getPoeCurrent()), MILLI(Units.AMPERE));
127 state = UnDefType.UNDEF;
132 private @Nullable UniFiPortTable getPort(final Map<Integer, UniFiPortTable> ports) {
133 return ports.get(config.getPortNumber());
137 protected boolean handleCommand(final UniFiController controller, final Map<Integer, UniFiPortTable> ports,
138 final ChannelUID channelUID, final Command command) throws UniFiException {
139 final String channelID = channelUID.getIdWithoutGroup();
142 case CHANNEL_PORT_POE_ENABLE:
143 if (command instanceof OnOffType) {
144 return handleModeCommand(controller, ports, getPort(ports),
145 OnOffType.ON == command ? poeEnableMode : CHANNEL_ENABLE_PARAMETER_MODE_OFF);
148 case CHANNEL_PORT_POE_MODE:
149 if (command instanceof StringType) {
150 return handleModeCommand(controller, ports, getPort(ports), command.toFullString());
153 case CHANNEL_PORT_POE_CMD:
154 if (command instanceof StringType) {
155 return handleCmd(controller, getPort(ports), command.toFullString());
163 private boolean handleModeCommand(final UniFiController controller, final Map<Integer, UniFiPortTable> ports,
164 final @Nullable UniFiPortTable portToUpdate, final String poeMode) throws UniFiException {
165 final UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
167 if (device == null || portToUpdate == null) {
168 logger.info("Could not change the PoE port state for thing '{}': device {} or portToUpdate {} null",
169 getThing().getUID(), device, portToUpdate);
172 final UnfiPortOverride override = new UnfiPortOverride();
173 override.setPortIdx(portToUpdate.getPortIdx());
174 override.setPortconfId(portToUpdate.getPortconfId());
175 override.setPoeMode(poeMode);
176 final Map<Integer, UnfiPortOverride> newMap = new HashMap<>(ports);
178 newMap.put(portToUpdate.getPortIdx(), override);
179 controller.poeMode(device, newMap);
185 private boolean handleCmd(final UniFiController controller, @Nullable final UniFiPortTable portToUpdate,
186 final String command) throws UniFiException {
187 final UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
188 if (device == null || portToUpdate == null) {
189 logger.info("Could not change the PoE port state for thing '{}': device {} or portToUpdate {} null",
190 getThing().getUID(), device, portToUpdate);
193 if (CHANNEL_PORT_POE_CMD_POWER_CYCLE.equalsIgnoreCase(command.replaceAll("[- ]", ""))) {
194 controller.poePowerCycle(device, portToUpdate.getPortIdx());
197 logger.info("Unknown command '{}' given to PoE port for thing '{}': device {} or portToUpdate {} null",
198 command, getThing().getUID(), device, portToUpdate);