Skip to content

Commit

Permalink
Merge branch 'openhab:main' into bindinngs/linkTap
Browse files Browse the repository at this point in the history
  • Loading branch information
dag81 authored Aug 13, 2024
2 parents 1729cf3 + 1b23f2b commit 18bc9e5
Show file tree
Hide file tree
Showing 64 changed files with 1,029 additions and 601 deletions.
24 changes: 12 additions & 12 deletions bundles/org.openhab.binding.freeboxos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,15 @@ The following channels are supported:

The following actions are available in rules/scripting:

| Thing Type | Action Name | Parameters | Description |
|-------------|------------------|-------------------------|------------------------------------------------------|
| host | wol | None | Sends a wake on lan packet to the lan connected host |
| player | reboot | None | Reboots the player device |
| player | sendKey | key: String | Send a key (remote emulation) to the player |
| player | sendLongKey | key: String | Sends the key emulating a longpress on the button |
| player | sendMultipleKeys | keys: String | Sends multiple keys to the player, comma separated |
| player | sendKeyRepeat | key: String, count: int | Sends the key multiple times |
| server | reboot | None | Reboots the Freebox Server |
| freeplug | reset | None | Resets the Freeplug |
| call | reset | None | Clears the call log queue |
| repeater | reboot | None | Reboots the Repeater |
| Thing Type | Action Name | Parameters | Description |
|-----------------------|------------------|-------------------------|------------------------------------------------------|
| host, wifihost | wol | None | Sends a wake on lan packet to the lan connected host |
| active-player | rebootPlayer | None | Reboots the Freebox Player |
| active-player, player | sendKey | key: String | Sends a key (remote emulation) to the player |
| active-player, player | sendLongKey | key: String | Sends a key emulating a longpress on the button |
| active-player, player | sendMultipleKeys | keys: String | Sends multiple keys to the player, comma separated |
| active-player, player | sendKeyRepeat | key: String, count: int | Sends a key multiple times |
| delta, revolution | rebootServer | None | Reboots the Freebox Server |
| freeplug | resetPlug | None | Resets the Freeplug |
| call | resetCalls | None | Deletes all calls logged in the queue |
| repeater | rebootRepeater | None | Reboots the Free Repeater |
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class ActivePlayerActions extends PlayerActions {
private final Logger logger = LoggerFactory.getLogger(ActivePlayerActions.class);

@RuleAction(label = "reboot freebox player", description = "Reboots the Freebox Player")
public void reboot() {
public void rebootPlayer() {
logger.debug("Player reboot called");
PlayerHandler localHandler = this.handler;
if (localHandler instanceof ActivePlayerHandler apHandler) {
Expand All @@ -45,7 +45,11 @@ public void reboot() {
}
}

public static void reboot(ThingActions actions) {
((ActivePlayerActions) actions).reboot();
public static void rebootPlayer(ThingActions actions) {
if (actions instanceof ActivePlayerActions activePlayerActions) {
activePlayerActions.rebootPlayer();
} else {
throw new IllegalArgumentException("actions parameter is not an ActivePlayerActions class.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public void setThingHandler(@Nullable ThingHandler handler) {
return handler;
}

@RuleAction(label = "clear call queue", description = "Delete all call logged in the queue")
public void reset() {
@RuleAction(label = "clear call queue", description = "Deletes all calls logged in the queue")
public void resetCalls() {
logger.debug("Call log clear called");
CallHandler localHandler = handler;
if (localHandler != null) {
Expand All @@ -58,4 +58,12 @@ public void reset() {
logger.warn("Call Action service ThingHandler is null");
}
}

public static void resetCalls(ThingActions actions) {
if (actions instanceof CallActions callActions) {
callActions.resetCalls();
} else {
throw new IllegalArgumentException("actions parameter is not a CallActions class.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void setThingHandler(@Nullable ThingHandler handler) {
}

@RuleAction(label = "reset freeplug", description = "Resets the Freeplug")
public void reset() {
public void resetPlug() {
logger.debug("Freeplug reset requested");
FreeplugHandler plugHandler = this.handler;
if (plugHandler != null) {
Expand All @@ -58,4 +58,12 @@ public void reset() {
logger.warn("Freeplug Action service ThingHandler is null");
}
}

public static void resetPlug(ThingActions actions) {
if (actions instanceof FreeplugActions freeplugActions) {
freeplugActions.resetPlug();
} else {
throw new IllegalArgumentException("actions parameter is not a FreeplugActions class.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void setThingHandler(@Nullable ThingHandler handler) {
return this.handler;
}

@RuleAction(label = "wol host", description = "Awakes a lan host")
@RuleAction(label = "wol host", description = "Sends a wake on lan packet to the lan connected host")
public void wol() {
logger.debug("Host WOL called");
HostHandler hostHandler = this.handler;
Expand All @@ -58,4 +58,12 @@ public void wol() {
logger.warn("LanHost Action service ThingHandler is null");
}
}

public static void wol(ThingActions actions) {
if (actions instanceof HostActions hostActions) {
hostActions.wol();
} else {
throw new IllegalArgumentException("actions parameter is not a HostHandler class.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,36 @@ public void sendKeyRepeat(@ActionInput(name = "key") String key, @ActionInput(na
logger.warn("Freebox Player Action service ThingHandler is null");
}
}

public static void sendKey(ThingActions actions, String key) {
if (actions instanceof PlayerActions playerActions) {
playerActions.sendKey(key);
} else {
throw new IllegalArgumentException("actions parameter is not a PlayerActions class.");
}
}

public static void sendLongKey(ThingActions actions, String key) {
if (actions instanceof PlayerActions playerActions) {
playerActions.sendLongKey(key);
} else {
throw new IllegalArgumentException("actions parameter is not a PlayerActions class.");
}
}

public static void sendMultipleKeys(ThingActions actions, String keys) {
if (actions instanceof PlayerActions playerActions) {
playerActions.sendMultipleKeys(keys);
} else {
throw new IllegalArgumentException("actions parameter is not a PlayerActions class.");
}
}

public static void sendKeyRepeat(ThingActions actions, String key, int count) {
if (actions instanceof PlayerActions playerActions) {
playerActions.sendKeyRepeat(key, count);
} else {
throw new IllegalArgumentException("actions parameter is not a PlayerActions class.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void setThingHandler(@Nullable ThingHandler handler) {
}

@RuleAction(label = "reboot free repeater", description = "Reboots the Free Repeater")
public void reboot() {
public void rebootRepeater() {
logger.debug("Repeater reboot called");
RepeaterHandler localHandler = this.handler;
if (localHandler != null) {
Expand All @@ -58,4 +58,12 @@ public void reboot() {
logger.warn("Repeater Action service ThingHandler is null");
}
}

public static void rebootRepeater(ThingActions actions) {
if (actions instanceof RepeaterActions repeaterActions) {
repeaterActions.rebootRepeater();
} else {
throw new IllegalArgumentException("actions parameter is not a RepeaterActions class.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,21 @@ public void setThingHandler(@Nullable ThingHandler handler) {
}

@RuleAction(label = "reboot freebox server", description = "Reboots the Freebox Server")
public void reboot() {
public void rebootServer() {
logger.debug("Server reboot called");
ServerHandler serverHandler = this.handler;
if (serverHandler != null) {
serverHandler.reboot();
} else {
logger.warn("Freebox Action service ThingHandler is null");
logger.warn("Freebox Server Action service ThingHandler is null");
}
}

public static void rebootServer(ThingActions actions) {
if (actions instanceof ServerActions serverActions) {
serverActions.rebootServer();
} else {
throw new IllegalArgumentException("actions parameter is not a ServerActions class.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public class FreeboxOsSession {
private @Nullable Session session;
private String appToken = "";
private int wsReconnectInterval;
@Nullable
private Boolean vmSupported;

public enum BoxModel {
FBXGW_R1_FULL, // Freebox Server (v6) revision 1
Expand Down Expand Up @@ -85,7 +87,9 @@ public void initialize(FreeboxOsConfiguration config) throws FreeboxException, I
ApiVersion.class, null, null);
this.uriBuilder = config.getUriBuilder(version.baseUrl());
this.wsReconnectInterval = config.wsReconnectInterval;
this.vmSupported = null;
getManager(LoginManager.class);
getManager(SystemManager.class);
getManager(NetShareManager.class);
getManager(LanManager.class);
getManager(WifiManager.class);
Expand All @@ -95,9 +99,13 @@ public void initialize(FreeboxOsConfiguration config) throws FreeboxException, I

public void openSession(String appToken) throws FreeboxException {
Session newSession = getManager(LoginManager.class).openSession(appToken);
getManager(WebSocketManager.class).openSession(newSession.sessionToken(), wsReconnectInterval);
session = newSession;
this.appToken = appToken;
if (vmSupported == null) {
vmSupported = getManager(SystemManager.class).getConfig().modelInfo().hasVm();
}
getManager(WebSocketManager.class).openSession(newSession.sessionToken(), wsReconnectInterval,
Boolean.TRUE.equals(vmSupported));
}

public String grant() throws FreeboxException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ public class WebSocketManager extends RestManager implements WebSocketListener {
@Nullable
private String sessionToken;
private int reconnectInterval;
private boolean vmSupported = true;
private boolean retryConnectWithoutVm = false;
private boolean vmSupported;

private record Register(String action, List<String> events) {
Register(String... events) {
Expand All @@ -101,9 +100,10 @@ public String getEvent() {
}
}

public void openSession(@Nullable String sessionToken, int reconnectInterval) {
public void openSession(@Nullable String sessionToken, int reconnectInterval, boolean vmSupported) {
this.sessionToken = sessionToken;
this.reconnectInterval = reconnectInterval;
this.vmSupported = vmSupported;
if (reconnectInterval > 0) {
try {
client.start();
Expand Down Expand Up @@ -190,12 +190,6 @@ public void onWebSocketText(@NonNullByDefault({}) String message) {
default:
logger.warn("Unhandled notification received: {}", result.action);
}
} else if (result.action == Action.REGISTER) {
logger.debug("Event registration failed!");
if (vmSupported && "unsupported event vm_state_changed".equals(result.msg)) {
vmSupported = false;
retryConnectWithoutVm = true;
}
}
}

Expand Down Expand Up @@ -233,11 +227,6 @@ private void handleNotification(WebSocketResponse response) {
public void onWebSocketClose(int statusCode, @NonNullByDefault({}) String reason) {
logger.debug("Socket Closed: [{}] - reason {}", statusCode, reason);
this.wsSession = null;
if (retryConnectWithoutVm) {
logger.debug("Retry connecting websocket client without VM support");
retryConnectWithoutVm = false;
startReconnect();
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -50,6 +51,7 @@ public class ActivePlayerHandler extends PlayerHandler implements FreeDeviceIntf

public ActivePlayerHandler(Thing thing) {
super(thing);
statusDrivenByLanConnectivity = false;
eventChannelUID = new ChannelUID(getThing().getUID(), SYS_INFO, BOX_EVENT);
}

Expand All @@ -69,9 +71,24 @@ void initializeProperties(Map<String, String> properties) throws FreeboxExceptio
@Override
protected void internalPoll() throws FreeboxException {
super.internalPoll();
if (thing.getStatus().equals(ThingStatus.ONLINE)) {
poll();
}

@Override
protected void internalForcePoll() throws FreeboxException {
super.internalForcePoll();
poll();
}

private void poll() throws FreeboxException {
if (reachable) {
Player player = getManager(PlayerManager.class).getDevice(getClientId());
updateStatus(player.reachable() ? ThingStatus.ONLINE : ThingStatus.OFFLINE);
logger.debug("{}: poll with player.reachable() = {}", thing.getUID(), player.reachable());
if (player.reachable()) {
updateStatus(ThingStatus.ONLINE);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "@text/info-player-not-reachable");
}
if (player.reachable()) {
Status status = getManager(PlayerManager.class).getPlayerStatus(getClientId());
if (status != null) {
Expand All @@ -89,6 +106,9 @@ protected void internalPoll() throws FreeboxException {
}
}
updateChannelQuantity(SYS_INFO, UPTIME, uptime, Units.SECOND);
} else {
logger.debug("{}: poll with reachable={}", thing.getUID(), reachable);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "@text/info-player-not-reachable");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ private void startRefreshJob() {
ThingStatusDetail detail = thing.getStatusInfo().getStatusDetail();
if (ThingStatusDetail.DUTY_CYCLE.equals(detail)) {
try {
internalPoll();
internalForcePoll();
} catch (FreeboxException ignore) {
// An exception is normal if the box is rebooting then let's try again later...
addJob("Initialize", this::initialize, 10, TimeUnit.SECONDS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.openhab.binding.freeboxos.internal.config.ApiConsumerConfiguration;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -46,6 +47,8 @@ public class HostHandler extends ApiConsumerHandler {
// We start in pull mode and switch to push after a first update...
protected boolean pushSubscribed = false;

protected boolean statusDrivenByLanConnectivity = true;

protected boolean reachable;

private int tryConfigureMediaSink = 1;
Expand Down Expand Up @@ -93,7 +96,8 @@ protected void internalPoll() throws FreeboxException {

LanHost host = getLanHost();
updateConnectivityChannels(host);
logger.debug("Switching to push mode - refreshInterval will now be ignored for Connectivity data");
logger.debug("{}: switching to push mode - refreshInterval will now be ignored for Connectivity data",
thing.getUID());
pushSubscribed = getManager(WebSocketManager.class).registerListener(host.getMac(), this);
}

Expand All @@ -114,10 +118,17 @@ protected LanHost getLanHost() throws FreeboxException {
}

public void updateConnectivityChannels(LanHost host) {
logger.debug("{}: updateConnectivityChannels with host.reachable() = {}", thing.getUID(), host.reachable());
updateChannelOnOff(CONNECTIVITY, REACHABLE, host.reachable());
updateChannelDateTimeState(CONNECTIVITY, LAST_SEEN, host.getLastSeen());
updateChannelString(CONNECTIVITY, IP_ADDRESS, host.getIpv4());
updateStatus(host.reachable() ? ThingStatus.ONLINE : ThingStatus.OFFLINE);
if (statusDrivenByLanConnectivity) {
if (host.reachable()) {
updateStatus(ThingStatus.ONLINE);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "@text/info-host-not-reachable");
}
}
// We will check and configure audio sink only when the host reachability changed
if (reachable != host.reachable()) {
reachable = host.reachable();
Expand Down
Loading

0 comments on commit 18bc9e5

Please sign in to comment.