]> git.basschouten.com Git - openhab-addons.git/blob
a7f251f502a0a01daee2ec6aeff37717ec212b2a
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.mikrotik.internal.handler;
14
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;
18
19 import java.math.BigDecimal;
20
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;
45
46 /**
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.
50  *
51  * @author Oleg Vivtash - Initial contribution
52  */
53 @NonNullByDefault
54 public class MikrotikInterfaceThingHandler extends MikrotikBaseThingHandler<InterfaceThingConfig> {
55     private final Logger logger = LoggerFactory.getLogger(MikrotikInterfaceThingHandler.class);
56
57     private @Nullable RouterosInterfaceBase iface;
58
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);
63
64     public static boolean supportsThingType(ThingTypeUID thingTypeUID) {
65         return MikrotikBindingConstants.THING_TYPE_INTERFACE.equals(thingTypeUID);
66     }
67
68     public MikrotikInterfaceThingHandler(Thing thing) {
69         super(thing);
70     }
71
72     @Override
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);
82             }
83         }
84         super.updateStatus(status, statusDetail, description);
85     }
86
87     @Override
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,
96                         getThing().getUID());
97                 updateStatus(OFFLINE, GONE, statusMsg);
98             } else {
99                 txByteRate.update(rosInterface.getTxBytes());
100                 rxByteRate.update(rosInterface.getRxBytes());
101                 txPacketRate.update(rosInterface.getTxPackets());
102                 rxPacketRate.update(rosInterface.getRxPackets());
103             }
104         }
105     }
106
107     @Override
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;
113         if (iface == null) {
114             newState = UnDefType.NULL;
115         } else {
116             switch (channelID) {
117                 case MikrotikBindingConstants.CHANNEL_NAME:
118                     newState = StateUtil.stringOrNull(iface.getName());
119                     break;
120                 case MikrotikBindingConstants.CHANNEL_COMMENT:
121                     newState = StateUtil.stringOrNull(iface.getComment());
122                     break;
123                 case MikrotikBindingConstants.CHANNEL_TYPE:
124                     newState = StateUtil.stringOrNull(iface.getType());
125                     break;
126                 case MikrotikBindingConstants.CHANNEL_MAC:
127                     newState = StateUtil.stringOrNull(iface.getMacAddress());
128                     break;
129                 case MikrotikBindingConstants.CHANNEL_ENABLED:
130                     newState = StateUtil.boolOrNull(iface.isEnabled());
131                     break;
132                 case MikrotikBindingConstants.CHANNEL_CONNECTED:
133                     newState = StateUtil.boolOrNull(iface.isConnected());
134                     break;
135                 case MikrotikBindingConstants.CHANNEL_LAST_LINK_DOWN_TIME:
136                     newState = StateUtil.timeOrNull(iface.getLastLinkDownTime());
137                     break;
138                 case MikrotikBindingConstants.CHANNEL_LAST_LINK_UP_TIME:
139                     newState = StateUtil.timeOrNull(iface.getLastLinkUpTime());
140                     break;
141                 case MikrotikBindingConstants.CHANNEL_LINK_DOWNS:
142                     newState = StateUtil.intOrNull(iface.getLinkDowns());
143                     break;
144                 case MikrotikBindingConstants.CHANNEL_TX_DATA_RATE:
145                     newState = StateUtil.qtyMegabitPerSecOrNull(txByteRate.getMegabitRate());
146                     break;
147                 case MikrotikBindingConstants.CHANNEL_RX_DATA_RATE:
148                     newState = StateUtil.qtyMegabitPerSecOrNull(rxByteRate.getMegabitRate());
149                     break;
150                 case MikrotikBindingConstants.CHANNEL_TX_PACKET_RATE:
151                     newState = StateUtil.floatOrNull(txPacketRate.getRate());
152                     break;
153                 case MikrotikBindingConstants.CHANNEL_RX_PACKET_RATE:
154                     newState = StateUtil.floatOrNull(rxPacketRate.getRate());
155                     break;
156                 case MikrotikBindingConstants.CHANNEL_TX_BYTES:
157                     newState = StateUtil.bigIntOrNull(iface.getTxBytes());
158                     break;
159                 case MikrotikBindingConstants.CHANNEL_RX_BYTES:
160                     newState = StateUtil.bigIntOrNull(iface.getRxBytes());
161                     break;
162                 case MikrotikBindingConstants.CHANNEL_TX_PACKETS:
163                     newState = StateUtil.bigIntOrNull(iface.getTxPackets());
164                     break;
165                 case MikrotikBindingConstants.CHANNEL_RX_PACKETS:
166                     newState = StateUtil.bigIntOrNull(iface.getRxPackets());
167                     break;
168                 case MikrotikBindingConstants.CHANNEL_TX_DROPS:
169                     newState = StateUtil.bigIntOrNull(iface.getTxDrops());
170                     break;
171                 case MikrotikBindingConstants.CHANNEL_RX_DROPS:
172                     newState = StateUtil.bigIntOrNull(iface.getRxDrops());
173                     break;
174                 case MikrotikBindingConstants.CHANNEL_TX_ERRORS:
175                     newState = StateUtil.bigIntOrNull(iface.getTxErrors());
176                     break;
177                 case MikrotikBindingConstants.CHANNEL_RX_ERRORS:
178                     newState = StateUtil.bigIntOrNull(iface.getRxErrors());
179                     break;
180                 default:
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);
193                     }
194             }
195         }
196
197         if (!newState.equals(oldState)) {
198             updateState(channelID, newState);
199             currentState.put(channelID, newState);
200         }
201     }
202
203     protected State getEtherIterfaceChannelState(String channelID) {
204         RouterosEthernetInterface etherIface = (RouterosEthernetInterface) this.iface;
205         if (etherIface == null) {
206             return UnDefType.UNDEF;
207         }
208
209         switch (channelID) {
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());
216             default:
217                 return UnDefType.UNDEF;
218         }
219     }
220
221     protected State getCapIterfaceChannelState(String channelID) {
222         RouterosCapInterface capIface = (RouterosCapInterface) this.iface;
223         if (capIface == null) {
224             return UnDefType.UNDEF;
225         }
226
227         switch (channelID) {
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());
236             default:
237                 return UnDefType.UNDEF;
238         }
239     }
240
241     protected State getWlanIterfaceChannelState(String channelID) {
242         RouterosWlanInterface wlIface = (RouterosWlanInterface) this.iface;
243         if (wlIface == null) {
244             return UnDefType.UNDEF;
245         }
246
247         switch (channelID) {
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());
256             default:
257                 return UnDefType.UNDEF;
258         }
259     }
260
261     protected State getPPPoECliChannelState(String channelID) {
262         RouterosPPPoECliInterface pppCli = (RouterosPPPoECliInterface) this.iface;
263         if (pppCli == null) {
264             return UnDefType.UNDEF;
265         }
266
267         switch (channelID) {
268             case MikrotikBindingConstants.CHANNEL_STATE:
269                 return StateUtil.stringOrNull(pppCli.getStatus());
270             case MikrotikBindingConstants.CHANNEL_UP_SINCE:
271                 return StateUtil.timeOrNull(pppCli.getUptimeStart());
272             default:
273                 return UnDefType.UNDEF;
274         }
275     }
276
277     protected State getL2TPSrvChannelState(String channelID) {
278         RouterosL2TPSrvInterface vpnSrv = (RouterosL2TPSrvInterface) this.iface;
279         if (vpnSrv == null) {
280             return UnDefType.UNDEF;
281         }
282
283         switch (channelID) {
284             case MikrotikBindingConstants.CHANNEL_STATE:
285                 return StateUtil.stringOrNull(vpnSrv.getEncoding());
286             case MikrotikBindingConstants.CHANNEL_UP_SINCE:
287                 return StateUtil.timeOrNull(vpnSrv.getUptimeStart());
288             default:
289                 return UnDefType.UNDEF;
290         }
291     }
292
293     protected State getL2TPCliChannelState(String channelID) {
294         RouterosL2TPCliInterface vpnCli = (RouterosL2TPCliInterface) this.iface;
295         if (vpnCli == null) {
296             return UnDefType.UNDEF;
297         }
298
299         switch (channelID) {
300             case MikrotikBindingConstants.CHANNEL_STATE:
301                 return StateUtil.stringOrNull(vpnCli.getEncoding());
302             case MikrotikBindingConstants.CHANNEL_UP_SINCE:
303                 return StateUtil.timeOrNull(vpnCli.getUptimeStart());
304             default:
305                 return UnDefType.UNDEF;
306         }
307     }
308
309     @Override
310     protected void executeCommand(ChannelUID channelUID, Command command) {
311         if (iface == null) {
312             return;
313         }
314         logger.warn("Ignoring unsupported command = {} for channel = {}", command, channelUID);
315     }
316 }