2 * Copyright (c) 2010-2024 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.RouterosLTEInterface;
32 import org.openhab.binding.mikrotik.internal.model.RouterosPPPCliInterface;
33 import org.openhab.binding.mikrotik.internal.model.RouterosPPPoECliInterface;
34 import org.openhab.binding.mikrotik.internal.model.RouterosWlanInterface;
35 import org.openhab.binding.mikrotik.internal.util.RateCalculator;
36 import org.openhab.binding.mikrotik.internal.util.StateUtil;
37 import org.openhab.core.thing.ChannelUID;
38 import org.openhab.core.thing.Thing;
39 import org.openhab.core.thing.ThingStatus;
40 import org.openhab.core.thing.ThingStatusDetail;
41 import org.openhab.core.thing.ThingTypeUID;
42 import org.openhab.core.types.Command;
43 import org.openhab.core.types.State;
44 import org.openhab.core.types.UnDefType;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
49 * The {@link MikrotikInterfaceThingHandler} is a {@link MikrotikBaseThingHandler} subclass that wraps shared
50 * functionality for all interface things of different types. It is responsible for handling commands, which are
51 * sent to one of the channels and emit channel updates whenever required.
53 * @author Oleg Vivtash - Initial contribution
56 public class MikrotikInterfaceThingHandler extends MikrotikBaseThingHandler<InterfaceThingConfig> {
57 private final Logger logger = LoggerFactory.getLogger(MikrotikInterfaceThingHandler.class);
59 private @Nullable RouterosInterfaceBase iface;
61 private final RateCalculator txByteRate = new RateCalculator(BigDecimal.ZERO);
62 private final RateCalculator rxByteRate = new RateCalculator(BigDecimal.ZERO);
63 private final RateCalculator txPacketRate = new RateCalculator(BigDecimal.ZERO);
64 private final RateCalculator rxPacketRate = new RateCalculator(BigDecimal.ZERO);
66 public static boolean supportsThingType(ThingTypeUID thingTypeUID) {
67 return MikrotikBindingConstants.THING_TYPE_INTERFACE.equals(thingTypeUID);
70 public MikrotikInterfaceThingHandler(Thing thing) {
75 protected void updateStatus(ThingStatus status, ThingStatusDetail statusDetail, @Nullable String description) {
76 RouterosDevice routeros = getRouterOs();
77 InterfaceThingConfig cfg = this.config;
78 if (routeros != null && cfg != null) {
79 if (status == ONLINE || (status == OFFLINE && statusDetail == ThingStatusDetail.COMMUNICATION_ERROR)) {
80 routeros.registerForMonitoring(cfg.name);
81 } else if (status == OFFLINE
82 && (statusDetail == ThingStatusDetail.CONFIGURATION_ERROR || statusDetail == GONE)) {
83 routeros.unregisterForMonitoring(cfg.name);
86 super.updateStatus(status, statusDetail, description);
90 protected void refreshModels() {
91 RouterosDevice routeros = getRouterOs();
92 InterfaceThingConfig cfg = this.config;
93 if (routeros != null && cfg != null) {
94 RouterosInterfaceBase rosInterface = routeros.findInterface(cfg.name);
95 this.iface = rosInterface;
96 if (rosInterface == null) {
97 String statusMsg = String.format("RouterOS interface %s is not found for thing %s", cfg.name,
99 updateStatus(OFFLINE, GONE, statusMsg);
101 txByteRate.update(rosInterface.getTxBytes());
102 rxByteRate.update(rosInterface.getRxBytes());
103 txPacketRate.update(rosInterface.getTxPackets());
104 rxPacketRate.update(rosInterface.getRxPackets());
110 protected void refreshChannel(ChannelUID channelUID) {
111 String channelID = channelUID.getIdWithoutGroup();
112 State oldState = currentState.getOrDefault(channelID, UnDefType.NULL);
113 State newState = oldState;
114 RouterosInterfaceBase iface = this.iface;
116 newState = UnDefType.NULL;
119 case MikrotikBindingConstants.CHANNEL_NAME:
120 newState = StateUtil.stringOrNull(iface.getName());
122 case MikrotikBindingConstants.CHANNEL_COMMENT:
123 newState = StateUtil.stringOrNull(iface.getComment());
125 case MikrotikBindingConstants.CHANNEL_TYPE:
126 newState = StateUtil.stringOrNull(iface.getType());
128 case MikrotikBindingConstants.CHANNEL_MAC:
129 newState = StateUtil.stringOrNull(iface.getMacAddress());
131 case MikrotikBindingConstants.CHANNEL_ENABLED:
132 newState = StateUtil.boolSwitchOrNull(iface.isEnabled());
134 case MikrotikBindingConstants.CHANNEL_CONNECTED:
135 newState = StateUtil.boolContactOrNull(iface.isConnected());
137 case MikrotikBindingConstants.CHANNEL_LAST_LINK_DOWN_TIME:
138 newState = StateUtil.timeOrNull(iface.getLastLinkDownTime());
140 case MikrotikBindingConstants.CHANNEL_LAST_LINK_UP_TIME:
141 newState = StateUtil.timeOrNull(iface.getLastLinkUpTime());
143 case MikrotikBindingConstants.CHANNEL_LINK_DOWNS:
144 newState = StateUtil.intOrNull(iface.getLinkDowns());
146 case MikrotikBindingConstants.CHANNEL_TX_DATA_RATE:
147 newState = StateUtil.qtyMegabitPerSecOrNull(txByteRate.getMegabitRate());
149 case MikrotikBindingConstants.CHANNEL_RX_DATA_RATE:
150 newState = StateUtil.qtyMegabitPerSecOrNull(rxByteRate.getMegabitRate());
152 case MikrotikBindingConstants.CHANNEL_TX_PACKET_RATE:
153 newState = StateUtil.floatOrNull(txPacketRate.getRate());
155 case MikrotikBindingConstants.CHANNEL_RX_PACKET_RATE:
156 newState = StateUtil.floatOrNull(rxPacketRate.getRate());
158 case MikrotikBindingConstants.CHANNEL_TX_BYTES:
159 newState = StateUtil.bigIntOrNull(iface.getTxBytes());
161 case MikrotikBindingConstants.CHANNEL_RX_BYTES:
162 newState = StateUtil.bigIntOrNull(iface.getRxBytes());
164 case MikrotikBindingConstants.CHANNEL_TX_PACKETS:
165 newState = StateUtil.bigIntOrNull(iface.getTxPackets());
167 case MikrotikBindingConstants.CHANNEL_RX_PACKETS:
168 newState = StateUtil.bigIntOrNull(iface.getRxPackets());
170 case MikrotikBindingConstants.CHANNEL_TX_DROPS:
171 newState = StateUtil.bigIntOrNull(iface.getTxDrops());
173 case MikrotikBindingConstants.CHANNEL_RX_DROPS:
174 newState = StateUtil.bigIntOrNull(iface.getRxDrops());
176 case MikrotikBindingConstants.CHANNEL_TX_ERRORS:
177 newState = StateUtil.bigIntOrNull(iface.getTxErrors());
179 case MikrotikBindingConstants.CHANNEL_RX_ERRORS:
180 newState = StateUtil.bigIntOrNull(iface.getRxErrors());
183 if (iface instanceof RouterosEthernetInterface) {
184 newState = getEtherIterfaceChannelState(channelID);
185 } else if (iface instanceof RouterosCapInterface) {
186 newState = getCapIterfaceChannelState(channelID);
187 } else if (iface instanceof RouterosWlanInterface) {
188 newState = getWlanIterfaceChannelState(channelID);
189 } else if (iface instanceof RouterosPPPCliInterface) {
190 newState = getPPPCliChannelState(channelID);
191 } else if (iface instanceof RouterosPPPoECliInterface) {
192 newState = getPPPoECliChannelState(channelID);
193 } else if (iface instanceof RouterosL2TPSrvInterface) {
194 newState = getL2TPSrvChannelState(channelID);
195 } else if (iface instanceof RouterosL2TPCliInterface) {
196 newState = getL2TPCliChannelState(channelID);
197 } else if (iface instanceof RouterosLTEInterface) {
198 newState = getLTEChannelState(channelID);
203 if (!newState.equals(oldState)) {
204 updateState(channelID, newState);
205 currentState.put(channelID, newState);
209 protected State getEtherIterfaceChannelState(String channelID) {
210 RouterosEthernetInterface etherIface = (RouterosEthernetInterface) this.iface;
211 if (etherIface == null) {
212 return UnDefType.UNDEF;
216 case MikrotikBindingConstants.CHANNEL_DEFAULT_NAME:
217 return StateUtil.stringOrNull(etherIface.getDefaultName());
218 case MikrotikBindingConstants.CHANNEL_STATE:
219 return StateUtil.stringOrNull(etherIface.getState());
220 case MikrotikBindingConstants.CHANNEL_RATE:
221 return StateUtil.stringOrNull(etherIface.getRate());
223 return UnDefType.UNDEF;
227 protected State getCapIterfaceChannelState(String channelID) {
228 RouterosCapInterface capIface = (RouterosCapInterface) this.iface;
229 if (capIface == null) {
230 return UnDefType.UNDEF;
234 case MikrotikBindingConstants.CHANNEL_STATE:
235 return StateUtil.stringOrNull(capIface.getCurrentState());
236 case MikrotikBindingConstants.CHANNEL_RATE:
237 return StateUtil.stringOrNull(capIface.getRateSet());
238 case MikrotikBindingConstants.CHANNEL_REGISTERED_CLIENTS:
239 return StateUtil.intOrNull(capIface.getRegisteredClients());
240 case MikrotikBindingConstants.CHANNEL_AUTHORIZED_CLIENTS:
241 return StateUtil.intOrNull(capIface.getAuthorizedClients());
243 return UnDefType.UNDEF;
247 protected State getWlanIterfaceChannelState(String channelID) {
248 RouterosWlanInterface wlIface = (RouterosWlanInterface) this.iface;
249 if (wlIface == null) {
250 return UnDefType.UNDEF;
254 case MikrotikBindingConstants.CHANNEL_STATE:
255 return StateUtil.stringOrNull(wlIface.getCurrentState());
256 case MikrotikBindingConstants.CHANNEL_RATE:
257 return StateUtil.stringOrNull(wlIface.getRate());
258 case MikrotikBindingConstants.CHANNEL_REGISTERED_CLIENTS:
259 return StateUtil.intOrNull(wlIface.getRegisteredClients());
260 case MikrotikBindingConstants.CHANNEL_AUTHORIZED_CLIENTS:
261 return StateUtil.intOrNull(wlIface.getAuthorizedClients());
263 return UnDefType.UNDEF;
267 protected State getPPPoECliChannelState(String channelID) {
268 RouterosPPPoECliInterface pppCli = (RouterosPPPoECliInterface) this.iface;
269 if (pppCli == null) {
270 return UnDefType.UNDEF;
274 case MikrotikBindingConstants.CHANNEL_STATE:
275 return StateUtil.stringOrNull(pppCli.getStatus());
276 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
277 return StateUtil.timeOrNull(pppCli.getUptimeStart());
279 return UnDefType.UNDEF;
283 protected State getPPPCliChannelState(String channelID) {
284 RouterosPPPCliInterface pppCli = (RouterosPPPCliInterface) this.iface;
285 if (pppCli == null) {
286 return UnDefType.UNDEF;
290 case MikrotikBindingConstants.CHANNEL_STATE:
291 return StateUtil.stringOrNull(pppCli.getStatus());
292 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
293 return StateUtil.timeOrNull(pppCli.getUptimeStart());
295 return UnDefType.UNDEF;
299 protected State getL2TPSrvChannelState(String channelID) {
300 RouterosL2TPSrvInterface vpnSrv = (RouterosL2TPSrvInterface) this.iface;
301 if (vpnSrv == null) {
302 return UnDefType.UNDEF;
306 case MikrotikBindingConstants.CHANNEL_STATE:
307 return StateUtil.stringOrNull(vpnSrv.getEncoding());
308 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
309 return StateUtil.timeOrNull(vpnSrv.getUptimeStart());
311 return UnDefType.UNDEF;
315 protected State getL2TPCliChannelState(String channelID) {
316 RouterosL2TPCliInterface vpnCli = (RouterosL2TPCliInterface) this.iface;
317 if (vpnCli == null) {
318 return UnDefType.UNDEF;
322 case MikrotikBindingConstants.CHANNEL_STATE:
323 return StateUtil.stringOrNull(vpnCli.getEncoding());
324 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
325 return StateUtil.timeOrNull(vpnCli.getUptimeStart());
327 return UnDefType.UNDEF;
331 protected State getLTEChannelState(String channelID) {
332 RouterosLTEInterface lte = (RouterosLTEInterface) this.iface;
334 return UnDefType.UNDEF;
338 case MikrotikBindingConstants.CHANNEL_STATE:
339 return StateUtil.stringOrNull(lte.getStatus());
340 case MikrotikBindingConstants.CHANNEL_UP_SINCE:
341 return StateUtil.timeOrNull(lte.getUptimeStart());
343 return UnDefType.UNDEF;
348 protected void executeCommand(ChannelUID channelUID, Command command) {
352 logger.warn("Ignoring unsupported command = {} for channel = {}", command, channelUID);