2 * Copyright (c) 2010-2021 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.mikrotik.internal.handler;
15 import static org.openhab.core.thing.ThingStatus.OFFLINE;
16 import static org.openhab.core.thing.ThingStatus.ONLINE;
17 import static org.openhab.core.thing.ThingStatusDetail.GONE;
19 import java.math.BigDecimal;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.mikrotik.internal.MikrotikBindingConstants;
24 import org.openhab.binding.mikrotik.internal.config.InterfaceThingConfig;
25 import org.openhab.binding.mikrotik.internal.model.RouterosCapInterface;
26 import org.openhab.binding.mikrotik.internal.model.RouterosDevice;
27 import org.openhab.binding.mikrotik.internal.model.RouterosEthernetInterface;
28 import org.openhab.binding.mikrotik.internal.model.RouterosInterfaceBase;
29 import org.openhab.binding.mikrotik.internal.model.RouterosL2TPCliInterface;
30 import org.openhab.binding.mikrotik.internal.model.RouterosL2TPSrvInterface;
31 import org.openhab.binding.mikrotik.internal.model.RouterosPPPoECliInterface;
32 import org.openhab.binding.mikrotik.internal.model.RouterosWlanInterface;
33 import org.openhab.binding.mikrotik.internal.util.RateCalculator;
34 import org.openhab.binding.mikrotik.internal.util.StateUtil;
35 import org.openhab.core.thing.ChannelUID;
36 import org.openhab.core.thing.Thing;
37 import org.openhab.core.thing.ThingStatus;
38 import org.openhab.core.thing.ThingStatusDetail;
39 import org.openhab.core.thing.ThingTypeUID;
40 import org.openhab.core.types.Command;
41 import org.openhab.core.types.State;
42 import org.openhab.core.types.UnDefType;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * The {@link MikrotikInterfaceThingHandler} is a {@link MikrotikBaseThingHandler} subclass that wraps shared
48 * functionality for all interface things of different types. It is responsible for handling commands, which are
49 * sent to one of the channels and emit channel updates whenever required.
51 * @author Oleg Vivtash - Initial contribution
54 public class MikrotikInterfaceThingHandler extends MikrotikBaseThingHandler<InterfaceThingConfig> {
55 private final Logger logger = LoggerFactory.getLogger(MikrotikInterfaceThingHandler.class);
57 private @Nullable RouterosInterfaceBase iface;
59 private final RateCalculator txByteRate = new RateCalculator(BigDecimal.ZERO);
60 private final RateCalculator rxByteRate = new RateCalculator(BigDecimal.ZERO);
61 private final RateCalculator txPacketRate = new RateCalculator(BigDecimal.ZERO);
62 private final RateCalculator rxPacketRate = new RateCalculator(BigDecimal.ZERO);
64 public static boolean supportsThingType(ThingTypeUID thingTypeUID) {
65 return MikrotikBindingConstants.THING_TYPE_INTERFACE.equals(thingTypeUID);
68 public MikrotikInterfaceThingHandler(Thing thing) {
73 protected void updateStatus(ThingStatus status, ThingStatusDetail statusDetail, @Nullable String description) {
74 RouterosDevice routeros = getRouterOs();
75 InterfaceThingConfig cfg = this.config;
76 if (routeros != null && cfg != null) {
77 if (status == ONLINE || (status == OFFLINE && statusDetail == ThingStatusDetail.COMMUNICATION_ERROR)) {
78 routeros.registerForMonitoring(cfg.name);
79 } else if (status == OFFLINE
80 && (statusDetail == ThingStatusDetail.CONFIGURATION_ERROR || statusDetail == GONE)) {
81 routeros.unregisterForMonitoring(cfg.name);
84 super.updateStatus(status, statusDetail, description);
88 protected void refreshModels() {
89 RouterosDevice routeros = getRouterOs();
90 InterfaceThingConfig cfg = this.config;
91 if (routeros != null && cfg != null) {
92 RouterosInterfaceBase rosInterface = routeros.findInterface(cfg.name);
93 this.iface = rosInterface;
94 if (rosInterface == null) {
95 String statusMsg = String.format("Interface %s is not found in RouterOS for thing %s", cfg.name,
97 updateStatus(OFFLINE, GONE, statusMsg);
99 txByteRate.update(rosInterface.getTxBytes());
100 rxByteRate.update(rosInterface.getRxBytes());
101 txPacketRate.update(rosInterface.getTxPackets());
102 rxPacketRate.update(rosInterface.getRxPackets());
108 protected void refreshChannel(ChannelUID channelUID) {
109 String channelID = channelUID.getIdWithoutGroup();
110 State oldState = currentState.getOrDefault(channelID, UnDefType.NULL);
111 State newState = oldState;
112 RouterosInterfaceBase iface = this.iface;
114 newState = UnDefType.NULL;
117 case MikrotikBindingConstants.CHANNEL_NAME:
118 newState = StateUtil.stringOrNull(iface.getName());
120 case MikrotikBindingConstants.CHANNEL_COMMENT:
121 newState = StateUtil.stringOrNull(iface.getComment());
123 case MikrotikBindingConstants.CHANNEL_TYPE:
124 newState = StateUtil.stringOrNull(iface.getType());
126 case MikrotikBindingConstants.CHANNEL_MAC:
127 newState = StateUtil.stringOrNull(iface.getMacAddress());
129 case MikrotikBindingConstants.CHANNEL_ENABLED:
130 newState = StateUtil.boolSwitchOrNull(iface.isEnabled());
132 case MikrotikBindingConstants.CHANNEL_CONNECTED:
133 newState = StateUtil.boolContactOrNull(iface.isConnected());
135 case MikrotikBindingConstants.CHANNEL_LAST_LINK_DOWN_TIME:
136 newState = StateUtil.timeOrNull(iface.getLastLinkDownTime());
138 case MikrotikBindingConstants.CHANNEL_LAST_LINK_UP_TIME:
139 newState = StateUtil.timeOrNull(iface.getLastLinkUpTime());
141 case MikrotikBindingConstants.CHANNEL_LINK_DOWNS:
142 newState = StateUtil.intOrNull(iface.getLinkDowns());
144 case MikrotikBindingConstants.CHANNEL_TX_DATA_RATE:
145 newState = StateUtil.qtyMegabitPerSecOrNull(txByteRate.getMegabitRate());
147 case MikrotikBindingConstants.CHANNEL_RX_DATA_RATE:
148 newState = StateUtil.qtyMegabitPerSecOrNull(rxByteRate.getMegabitRate());
150 case MikrotikBindingConstants.CHANNEL_TX_PACKET_RATE:
151 newState = StateUtil.floatOrNull(txPacketRate.getRate());
153 case MikrotikBindingConstants.CHANNEL_RX_PACKET_RATE:
154 newState = StateUtil.floatOrNull(rxPacketRate.getRate());
156 case MikrotikBindingConstants.CHANNEL_TX_BYTES:
157 newState = StateUtil.bigIntOrNull(iface.getTxBytes());
159 case MikrotikBindingConstants.CHANNEL_RX_BYTES:
160 newState = StateUtil.bigIntOrNull(iface.getRxBytes());
162 case MikrotikBindingConstants.CHANNEL_TX_PACKETS:
163 newState = StateUtil.bigIntOrNull(iface.getTxPackets());
165 case MikrotikBindingConstants.CHANNEL_RX_PACKETS:
166 newState = StateUtil.bigIntOrNull(iface.getRxPackets());
168 case MikrotikBindingConstants.CHANNEL_TX_DROPS:
169 newState = StateUtil.bigIntOrNull(iface.getTxDrops());
171 case MikrotikBindingConstants.CHANNEL_RX_DROPS:
172 newState = StateUtil.bigIntOrNull(iface.getRxDrops());
174 case MikrotikBindingConstants.CHANNEL_TX_ERRORS:
175 newState = StateUtil.bigIntOrNull(iface.getTxErrors());
177 case MikrotikBindingConstants.CHANNEL_RX_ERRORS:
178 newState = StateUtil.bigIntOrNull(iface.getRxErrors());
181 if (iface instanceof RouterosEthernetInterface) {
182 newState = getEtherIterfaceChannelState(channelID);
183 } else if (iface instanceof RouterosCapInterface) {
184 newState = getCapIterfaceChannelState(channelID);
185 } else if (iface instanceof RouterosWlanInterface) {
186 newState = getWlanIterfaceChannelState(channelID);
187 } else if (iface instanceof RouterosPPPoECliInterface) {
188 newState = getPPPoECliChannelState(channelID);
189 } else if (iface instanceof RouterosL2TPSrvInterface) {
190 newState = getL2TPSrvChannelState(channelID);
191 } else if (iface instanceof RouterosL2TPCliInterface) {
192 newState = getL2TPCliChannelState(channelID);
197 if (!newState.equals(oldState)) {
198 updateState(channelID, newState);
199 currentState.put(channelID, newState);
203 protected State getEtherIterfaceChannelState(String channelID) {
204 RouterosEthernetInterface etherIface = (RouterosEthernetInterface) this.iface;
205 if (etherIface == null) {
206 return UnDefType.UNDEF;
210 case MikrotikBindingConstants.CHANNEL_DEFAULT_NAME:
211 return StateUtil.stringOrNull(etherIface.getDefaultName());
212 case MikrotikBindingConstants.CHANNEL_STATE:
213 return StateUtil.stringOrNull(etherIface.getState());
214 case MikrotikBindingConstants.CHANNEL_RATE:
215 return StateUtil.stringOrNull(etherIface.getRate());
217 return UnDefType.UNDEF;
221 protected State getCapIterfaceChannelState(String channelID) {
222 RouterosCapInterface capIface = (RouterosCapInterface) this.iface;
223 if (capIface == null) {
224 return UnDefType.UNDEF;
228 case MikrotikBindingConstants.CHANNEL_STATE:
229 return StateUtil.stringOrNull(capIface.getCurrentState());
230 case MikrotikBindingConstants.CHANNEL_RATE:
231 return StateUtil.stringOrNull(capIface.getRateSet());
232 case MikrotikBindingConstants.CHANNEL_REGISTERED_CLIENTS:
233 return StateUtil.intOrNull(capIface.getRegisteredClients());
234 case MikrotikBindingConstants.CHANNEL_AUTHORIZED_CLIENTS:
235 return StateUtil.intOrNull(capIface.getAuthorizedClients());
237 return UnDefType.UNDEF;
241 protected State getWlanIterfaceChannelState(String channelID) {
242 RouterosWlanInterface wlIface = (RouterosWlanInterface) this.iface;
243 if (wlIface == null) {
244 return UnDefType.UNDEF;
248 case MikrotikBindingConstants.CHANNEL_STATE:
249 return StateUtil.stringOrNull(wlIface.getCurrentState());
250 case MikrotikBindingConstants.CHANNEL_RATE:
251 return StateUtil.stringOrNull(wlIface.getRate());
252 case MikrotikBindingConstants.CHANNEL_REGISTERED_CLIENTS:
253 return StateUtil.intOrNull(wlIface.getRegisteredClients());
254 case MikrotikBindingConstants.CHANNEL_AUTHORIZED_CLIENTS:
255 return StateUtil.intOrNull(wlIface.getAuthorizedClients());
257 return UnDefType.UNDEF;
261 protected State getPPPoECliChannelState(String channelID) {
262 RouterosPPPoECliInterface pppCli = (RouterosPPPoECliInterface) this.iface;
263 if (pppCli == null) {
264 return UnDefType.UNDEF;
268 case MikrotikBindingConstants.CHANNEL_STATE:
269 return StateUtil.stringOrNull(pppCli.getStatus());
270 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
271 return StateUtil.timeOrNull(pppCli.getUptimeStart());
273 return UnDefType.UNDEF;
277 protected State getL2TPSrvChannelState(String channelID) {
278 RouterosL2TPSrvInterface vpnSrv = (RouterosL2TPSrvInterface) this.iface;
279 if (vpnSrv == null) {
280 return UnDefType.UNDEF;
284 case MikrotikBindingConstants.CHANNEL_STATE:
285 return StateUtil.stringOrNull(vpnSrv.getEncoding());
286 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
287 return StateUtil.timeOrNull(vpnSrv.getUptimeStart());
289 return UnDefType.UNDEF;
293 protected State getL2TPCliChannelState(String channelID) {
294 RouterosL2TPCliInterface vpnCli = (RouterosL2TPCliInterface) this.iface;
295 if (vpnCli == null) {
296 return UnDefType.UNDEF;
300 case MikrotikBindingConstants.CHANNEL_STATE:
301 return StateUtil.stringOrNull(vpnCli.getEncoding());
302 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
303 return StateUtil.timeOrNull(vpnCli.getUptimeStart());
305 return UnDefType.UNDEF;
310 protected void executeCommand(ChannelUID channelUID, Command command) {
314 logger.warn("Ignoring unsupported command = {} for channel = {}", command, channelUID);