]> git.basschouten.com Git - openhab-addons.git/blob
236f1c09128a5d55db2cd526a6a9aae8cc774ccf
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.unifi.internal.handler;
14
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;
27
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import javax.measure.quantity.ElectricCurrent;
32 import javax.measure.quantity.ElectricPotential;
33 import javax.measure.quantity.Power;
34
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;
57
58 /**
59  * A Power Over Ethernet (PoE) port on a UniFi switch.
60  *
61  * @author Hilbrand Bouwkamp - Initial contribution
62  */
63 @NonNullByDefault
64 public class UniFiPoePortThingHandler
65         extends UniFiBaseThingHandler<Map<Integer, UniFiPortTable>, UniFiPoePortThingConfig> {
66
67     private final Logger logger = LoggerFactory.getLogger(UniFiPoePortThingHandler.class);
68
69     private UniFiPoePortThingConfig config = new UniFiPoePortThingConfig();
70     private String poeEnableMode = "";
71
72     public UniFiPoePortThingHandler(final Thing thing) {
73         super(thing);
74     }
75
76     @Override
77     protected boolean initialize(final UniFiPoePortThingConfig config) {
78         this.config = config;
79         if (!config.isValid()) {
80             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
81                     "@text/error.thing.poe.offline.configuration_error");
82             return false;
83         }
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;
88         return true;
89     }
90
91     @Override
92     protected @Nullable Map<Integer, UniFiPortTable> getEntity(final UniFiControllerCache cache) {
93         return cache.getSwitchPorts(config.getMacAddress());
94     }
95
96     @Override
97     protected State getChannelState(final Map<Integer, UniFiPortTable> ports, final String channelId) {
98         final UniFiPortTable port = getPort(ports);
99
100         if (port == null) {
101             logger.debug("No PoE port for thing '{}' could be found in the data. Refresh ignored.",
102                     getThing().getUID());
103             return UnDefType.NULL;
104         }
105         final State state;
106
107         switch (channelId) {
108             case CHANNEL_ONLINE:
109                 state = OnOffType.from(port.isUp());
110                 break;
111             case CHANNEL_PORT_POE_ENABLE:
112                 state = OnOffType.from(port.isPoeEnabled());
113                 break;
114             case CHANNEL_PORT_POE_MODE:
115                 state = StringType.valueOf(port.getPoeMode());
116                 break;
117             case CHANNEL_PORT_POE_POWER:
118                 state = new QuantityType<Power>(Double.valueOf(port.getPoePower()), Units.WATT);
119                 break;
120             case CHANNEL_PORT_POE_VOLTAGE:
121                 state = new QuantityType<ElectricPotential>(Double.valueOf(port.getPoeVoltage()), Units.VOLT);
122                 break;
123             case CHANNEL_PORT_POE_CURRENT:
124                 state = new QuantityType<ElectricCurrent>(Double.valueOf(port.getPoeCurrent()), MILLI(Units.AMPERE));
125                 break;
126             default:
127                 state = UnDefType.UNDEF;
128         }
129         return state;
130     }
131
132     private @Nullable UniFiPortTable getPort(final Map<Integer, UniFiPortTable> ports) {
133         return ports.get(config.getPortNumber());
134     }
135
136     @Override
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();
140
141         switch (channelID) {
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);
146                 }
147                 break;
148             case CHANNEL_PORT_POE_MODE:
149                 if (command instanceof StringType) {
150                     return handleModeCommand(controller, ports, getPort(ports), command.toFullString());
151                 }
152                 break;
153             case CHANNEL_PORT_POE_CMD:
154                 if (command instanceof StringType) {
155                     return handleCmd(controller, getPort(ports), command.toFullString());
156                 }
157             default:
158                 return false;
159         }
160         return false;
161     }
162
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());
166
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);
170             return false;
171         } else {
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);
177
178             newMap.put(portToUpdate.getPortIdx(), override);
179             controller.poeMode(device, newMap);
180             refresh();
181             return true;
182         }
183     }
184
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);
191             return false;
192         } else {
193             if (CHANNEL_PORT_POE_CMD_POWER_CYCLE.equalsIgnoreCase(command.replaceAll("[- ]", ""))) {
194                 controller.poePowerCycle(device, portToUpdate.getPortIdx());
195                 return true;
196             } else {
197                 logger.info("Unknown command '{}' given to PoE port for thing '{}': device {} or portToUpdate {} null",
198                         command, getThing().getUID(), device, portToUpdate);
199                 return false;
200             }
201         }
202     }
203 }