Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mikrotik] Add PoE support #17351

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 44 additions & 32 deletions bundles/org.openhab.binding.mikrotik/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ configuration section in
Take note of the API port number as you'll need it below.
[SSL API connection](https://wiki.mikrotik.com/wiki/Manual:API-SSL) is not yet supported by this binding.
To connect to the RouterOS API, you will need to provide user credentials for the bridge thing.
You may use your current credentials that you use to manage your devices, but it is highly recommended to **create a read-only RouterOS user** since this binding only need to read data from the device.
To do this, proceed to <kbd>System -> Users</kbd> configuration section and add a user to the `read` group.
You may use your current credentials that you use to manage your devices, but it is highly recommended to **create a dedicated RouterOS user and group with limited permissions**.
To create dedicated group proceed to <kbd>System -> Users -> Groups</kbd> configuration section and create `openhab` group with `api` and `read` policies.
If you need to control PoE,- `write` policy also must be added.
To create user, proceed to <kbd>System -> Users</kbd> configuration section and add a `openhab` with `openhab` group.

> Thing type: `routeros`

Expand Down Expand Up @@ -122,35 +124,38 @@ be improved in future binding versions.

Common for all kinds of interfaces:

| Channel | Type | Description | Comment |
|---|---|---|---|
| type | String | Network interface type | |
| name | String | Network interface name | |
| comment | String | User-defined comment | |
| macAddress | String | MAC address of the client or interface | |
| enabled | Switch | Reflects enabled or disabled state | |
| connected | Contact | Reflects connected or disconnected state | |
| lastLinkDownTime | DateTime | Last time when link went down | |
| lastLinkUpTime | DateTime | Last time when link went up | |
| linkDowns | Number | Amount of link downs | |
| txRate | Number:DataTransferRate | Rate of data transmission in megabits per second | |
| rxRate | Number:DataTransferRate | Rate of data receiving in megabits per second | |
| txPacketRate | Number | Rate of data transmission in packets per second | |
| rxPacketRate | Number | Rate of data receiving in packets per second | |
| txBytes | Number:DataAmount | Amount of bytes transmitted | |
| rxBytes | Number:DataAmount | Amount of bytes received | |
| txPackets | Number | Amount of packets transmitted | |
| rxPackets | Number | Amount of packets received | |
| txDrops | Number | Amount of packets dropped during transmission | |
| rxDrops | Number | Amount of packets dropped during receiving | |
| txErrors | Number | Amount of errors during transmission | |
| rxErrors | Number | Amount of errors during receiving | |
| defaultName | String | Interface factory name | Populated only for `ether` interfaces |
| rate | String | Ethernet link rate | Populated only for `ether` interfaces |
| state | String | WiFi interface state | |
| registeredClients | Number | Amount of clients registered to WiFi interface | Populated only for `cap` interfaces |
| authorizedClients | Number | Amount of clients authorized by WiFi interface | Populated only for `cap` interfaces |
| upSince | DateTime | Time when thing got up | Populated only for `cap` interfaces |
| Channel | Type | Description | Comment |
|-------------------|------------------------|--------------------------------------------------|---|
| type | String | Network interface type | |
| name | String | Network interface name | |
| comment | String | User-defined comment | |
| macAddress | String | MAC address of the client or interface | |
| enabled | Switch | Reflects enabled or disabled state | |
| connected | Contact | Reflects connected or disconnected state | |
| lastLinkDownTime | DateTime | Last time when link went down | |
| lastLinkUpTime | DateTime | Last time when link went up | |
| linkDowns | Number | Amount of link downs | |
| txRate | Number:DataTransferRate | Rate of data transmission in megabits per second | |
| rxRate | Number:DataTransferRate | Rate of data receiving in megabits per second | |
| txPacketRate | Number | Rate of data transmission in packets per second | |
| rxPacketRate | Number | Rate of data receiving in packets per second | |
| txBytes | Number:DataAmount | Amount of bytes transmitted | |
| rxBytes | Number:DataAmount | Amount of bytes received | |
| txPackets | Number | Amount of packets transmitted | |
| rxPackets | Number | Amount of packets received | |
| txDrops | Number | Amount of packets dropped during transmission | |
| rxDrops | Number | Amount of packets dropped during receiving | |
| txErrors | Number | Amount of errors during transmission | |
| rxErrors | Number | Amount of errors during receiving | |
| state | String | Interface state | |
| defaultName | String | Interface factory name | Populated only for `ether` interfaces |
| rate | String | Ethernet link rate | Populated only for `ether` interfaces |
| poeOutState | String | Interface PoE state | Populated only for `ether` interfaces with PoE |
| poeOutStatus | String | Interface PoE status | Populated only for `ether` interfaces with PoE |
| poeOutPower | Number:Power | PoE out power consumption | Populated only for `ether` interfaces with PoE |
| registeredClients | Number | Amount of clients registered to WiFi interface | Populated only for `cap` interfaces |
| authorizedClients | Number | Amount of clients authorized by WiFi interface | Populated only for `cap` interfaces |
| upSince | DateTime | Time when thing got up | Populated only for `cap` interfaces |

## Text Configuration Example

Expand Down Expand Up @@ -189,7 +194,7 @@ String Eth_1_Name "Name" (gRB1Eth1) {
String Eth_1_Comment "Comment" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:comment"}
String Eth_1_Mac_Address "Mac address" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:macAddress"}
Switch Eth_1_Enabled "Enabled" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:enabled"}
Contact Eth_1_Connected "Connected" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:connected"}
Contact Eth_1_Connected "Connected" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:connected"}
DateTime Eth_1_Last_Link_Down_Time "Last link down" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:lastLinkDownTime"}
DateTime Eth_1_Last_Link_Up_Time "Last link up" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:lastLinkUpTime"}
Number Eth_1_Link_Downs "Link downs" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:linkDowns"}
Expand All @@ -209,6 +214,9 @@ String Eth_1_Default_Name "Default name" (gRB1Eth1) {
String Eth_1_Rate "Link rate" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:rate"}
String Eth_1_Auto_Negotiation "Auto negotiation" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:autoNegotiation"}
String Eth_1_State "State" (gRB1Eth1) {channel="mikrotik:interface:rb1:eth1:state"}
String Eth_1_POE_State "PoE State" (gRB1Eth1) ["Status", "Control"] {channel="mikrotik:interface:rb1:eth1:poeOutState"}
String Eth_1_POE_Status "PoE Status" (gRB1Eth1) ["Status"] {channel="mikrotik:interface:rb1:eth1:poeOutStatus"}
Number:Power Eth_1_POE_Power "PoE Power" (gRB1Eth1) ["Measurement", "Power"] {channel="mikrotik:interface:rb1:eth1:poeOutPower"}

Group gRB1Eth2 "Ethernet Interface 2"
String Eth_2_Type "Type" (gRB1Eth2) {channel="mikrotik:interface:rb1:eth2:type"}
Expand Down Expand Up @@ -236,6 +244,10 @@ String Eth_2_Default_Name "Default name" (gRB1Eth2) {
String Eth_2_Rate "Link rate" (gRB1Eth2) {channel="mikrotik:interface:rb1:eth2:rate"}
String Eth_2_Auto_Negotiation "Auto negotiation" (gRB1Eth2) {channel="mikrotik:interface:rb1:eth2:autoNegotiation"}
String Eth_2_State "State" (gRB1Eth2) {channel="mikrotik:interface:rb1:eth2:state"}
String Eth_2_POE_State "PoE State" (gRB1Eth2) ["Status", "Control"] {channel="mikrotik:interface:rb1:eth2:poeOutState"}
String Eth_2_POE_Status "PoE Status" (gRB1Eth2) ["Status"] {channel="mikrotik:interface:rb1:eth2:poeOutStatus"}
Number:Power Eth_2_POE_Power "PoE Power" (gRB1Eth2) ["Measurement", "Power"] {channel="mikrotik:interface:rb1:eth2:poeOutPower"}


Group gRB1Cap1 "CAPsMAN Inerface 1"
String Cap_1_Type "Type" (gRB1Cap1) {channel="mikrotik:interface:rb1:cap1:type"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ public class MikrotikBindingConstants {
public static final String CHANNEL_TX_ERRORS = "txErrors";
public static final String CHANNEL_RX_ERRORS = "rxErrors";

// Ethernet PoE
public static final String CHANNEL_POE_OUT_STATE = "poeOutState";
public static final String CHANNEL_POE_OUT_STATUS = "poeOutStatus";
public static final String CHANNEL_POE_OUT_POWER = "poeOutPower";

// Ethernet interface channel list
public static final String CHANNEL_DEFAULT_NAME = "defaultName";
public static final String CHANNEL_RATE = "rate";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,27 @@ public MikrotikBaseThingHandler(Thing thing) {
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("Handling command = {} for channel = {}", command, channelUID);
if (getThing().getStatus() == ONLINE) {
RouterosDevice routeros = getRouterOs();
if (routeros != null) {
if (command == REFRESH) {
refreshCache.getValue();
refreshChannel(channelUID);
} else {
try {
executeCommand(channelUID, command);
} catch (RuntimeException e) {
logger.warn("Unexpected error handling command = {} for channel = {} : {}", command, channelUID,
e.getMessage());
}
}
}
if (getThing().getStatus() != ONLINE) {
return;
}

RouterosDevice routeros = getRouterOs();
if (routeros == null) {
return;
}

if (command == REFRESH) {
refreshCache.getValue();
refreshChannel(channelUID);

return;
}

try {
executeCommand(channelUID, command);
} catch (RuntimeException e) {
logger.warn("Unexpected error handling command = {} for channel = {} : {}", command, channelUID,
e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import me.legrange.mikrotik.MikrotikApiException;

/**
* The {@link MikrotikInterfaceThingHandler} is a {@link MikrotikBaseThingHandler} subclass that wraps shared
* functionality for all interface things of different types. It is responsible for handling commands, which are
Expand Down Expand Up @@ -219,6 +221,12 @@ protected State getEtherIterfaceChannelState(String channelID) {
return StateUtil.stringOrNull(etherIface.getState());
case MikrotikBindingConstants.CHANNEL_RATE:
return StateUtil.stringOrNull(etherIface.getRate());
case MikrotikBindingConstants.CHANNEL_POE_OUT_STATE:
return StateUtil.stringOrNull(etherIface.getPOEOutState());
case MikrotikBindingConstants.CHANNEL_POE_OUT_STATUS:
return StateUtil.stringOrNull(etherIface.getPOEOutStatus());
case MikrotikBindingConstants.CHANNEL_POE_OUT_POWER:
return StateUtil.floatOrNull(etherIface.getPOEOutPower());
default:
return UnDefType.UNDEF;
}
Expand Down Expand Up @@ -346,9 +354,27 @@ protected State getLTEChannelState(String channelID) {

@Override
protected void executeCommand(ChannelUID channelUID, Command command) {
RouterosInterfaceBase iface = this.iface;
if (iface == null) {
return;
}
logger.warn("Ignoring unsupported command = {} for channel = {}", command, channelUID);

RouterosDevice routeros = getRouterOs();
if (routeros == null || !routeros.isConnected()) {
return;
}

try {
String channelID = channelUID.getIdWithoutGroup();
switch (channelID) {
case MikrotikBindingConstants.CHANNEL_POE_OUT_STATE:
routeros.setPOEOutState((RouterosEthernetInterface) iface, command.toString());
break;
default:
logger.warn("Ignoring unsupported command = {} for channel = {}", command, channelUID);
}
} catch (MikrotikApiException e) {
logger.warn("RouterOS command execution failed in {} due to Mikrotik API error", getThing().getUID(), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ protected void setProp(String key, String value) {
String val = propMap.get(key);
return val == null ? null : Float.valueOf(val);
}

protected @Nullable Long getLongProp(String key) {
String val = propMap.get(key);
return val == null ? null : Long.valueOf(val);
}
}
Loading