Skip to content

Commit 2e82fe6

Browse files
authored
[Keba] Implement thing action to set display text (openhab#18310)
* Implement Thing Action for setting display text Signed-off-by: Simon Spielmann <[email protected]>
1 parent 40215b6 commit 2e82fe6

File tree

4 files changed

+140
-7
lines changed

4 files changed

+140
-7
lines changed

bundles/org.openhab.binding.keba/README.md

+24
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ All devices support the following channels:
4848
| maxpilotcurrent | Number:ElectricCurrent | yes | current offered to the vehicle via control pilot signalization |
4949
| maxpilotcurrentdutycyle | Number:Dimensionless | yes | duty cycle of the control pilot signal |
5050

51+
## Rule Actions
52+
53+
Certain Keba models support setting the text on the built-in display.
54+
The text can be set via a rule action `setDisplay`. It comes in two variants:
55+
56+
```java
57+
rule "Set Display Text"
58+
when
59+
System reached start level 100
60+
then
61+
val keContactActions = getActions("keba", "keba:kecontact:1")
62+
// Default duration
63+
keContactActions.setDisplay("TEXT$1")
64+
// Explicit duration set
65+
keContactActions.setDisplay("TEXT$2", 5, 10)
66+
end
67+
```
68+
69+
| Parameter | Description |
70+
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
71+
| text | Text shown on the display. Maximum 23 ASCII characters can be used. `~` == Σ, `$` == blank, `,` == comma |
72+
| durationMin _(optional)_ | Defines the duration in seconds how long the text will displayed before another display command will be processed (internal MID metering relevant information may overrule this) |
73+
| durationMax _(optional)_ | Defines the duration in seconds how long the text will displayed if no additional display command follows. |
74+
5175
## Example
5276

5377
demo.Things:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2010-2025 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.keba.internal.handler;
14+
15+
import org.eclipse.jdt.annotation.NonNullByDefault;
16+
import org.eclipse.jdt.annotation.Nullable;
17+
import org.openhab.binding.keba.internal.KebaBindingConstants;
18+
import org.openhab.core.automation.annotation.ActionInput;
19+
import org.openhab.core.automation.annotation.RuleAction;
20+
import org.openhab.core.thing.binding.ThingActions;
21+
import org.openhab.core.thing.binding.ThingActionsScope;
22+
import org.openhab.core.thing.binding.ThingHandler;
23+
import org.osgi.service.component.annotations.Component;
24+
import org.osgi.service.component.annotations.ServiceScope;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
28+
/**
29+
* The {@link KeContactActions} is responsible for handling actions, which
30+
* are sent to the binding.
31+
*
32+
* @author Simon Spielmann - Initial contribution
33+
*/
34+
@Component(scope = ServiceScope.PROTOTYPE, service = KeContactActions.class)
35+
@ThingActionsScope(name = KebaBindingConstants.BINDING_ID)
36+
@NonNullByDefault
37+
public class KeContactActions implements ThingActions {
38+
private final Logger logger = LoggerFactory.getLogger(KeContactActions.class);
39+
private @Nullable KeContactHandler handler;
40+
41+
@Override
42+
public void setThingHandler(ThingHandler handler) {
43+
this.handler = (KeContactHandler) handler;
44+
}
45+
46+
@Override
47+
public @Nullable ThingHandler getThingHandler() {
48+
return handler;
49+
}
50+
51+
@RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
52+
public void setDisplay(
53+
@ActionInput(name = "text", label = "@text/actionInputTextLabel", description = "@text/actionInputTextDesc") @Nullable String text,
54+
@ActionInput(name = "durationMin", label = "@text/actionInputDurationMinLabel", description = "@text/actionInputDurationMinDesc") int durationMin,
55+
@ActionInput(name = "durationMax", label = "@text/actionInputDurationMaxLabel", description = "@text/actionInputDurationMaxDesc") int durationMax) {
56+
if (handler == null) {
57+
logger.warn("KeContact Action service ThingHandler is null!");
58+
return;
59+
}
60+
handler.setDisplay(text, durationMin, durationMax);
61+
}
62+
63+
public static void setDisplay(ThingActions actions, @Nullable String text, int durationMin, int durationMax) {
64+
((KeContactActions) actions).setDisplay(text, durationMin, durationMax);
65+
}
66+
67+
@RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
68+
public void setDisplay(
69+
@ActionInput(name = "text", label = "@text/actionInputTextLabel", description = "@text/actionInputTextDesc") @Nullable String text) {
70+
if (handler == null) {
71+
logger.warn("KeContact Action service ThingHandler is null!");
72+
return;
73+
}
74+
handler.setDisplay(text, -1, -1);
75+
}
76+
77+
public static void setDisplay(ThingActions actions, @Nullable String text) {
78+
((KeContactActions) actions).setDisplay(text);
79+
}
80+
}

bundles/org.openhab.binding.keba/src/main/java/org/openhab/binding/keba/internal/handler/KeContactHandler.java

+26-7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.net.Socket;
2121
import java.net.SocketAddress;
2222
import java.nio.ByteBuffer;
23+
import java.util.Collection;
24+
import java.util.List;
2325
import java.util.Map;
2426
import java.util.Map.Entry;
2527
import java.util.Objects;
@@ -41,6 +43,7 @@
4143
import org.openhab.core.thing.ThingStatus;
4244
import org.openhab.core.thing.ThingStatusDetail;
4345
import org.openhab.core.thing.binding.BaseThingHandler;
46+
import org.openhab.core.thing.binding.ThingHandlerService;
4447
import org.openhab.core.types.Command;
4548
import org.openhab.core.types.RefreshType;
4649
import org.openhab.core.types.State;
@@ -121,6 +124,11 @@ public void initialize() {
121124
}
122125
}
123126

127+
@Override
128+
public Collection<Class<? extends ThingHandlerService>> getServices() {
129+
return List.of(KeContactActions.class);
130+
}
131+
124132
private boolean isKebaReachable() throws IOException {
125133
boolean isReachable = false;
126134
SocketAddress sockAddr = new InetSocketAddress(getIPAddress(), SOCKET_CHECK_PORT_NUMBER);
@@ -571,13 +579,7 @@ public void handleCommand(ChannelUID channelUID, Command command) {
571579
}
572580
case CHANNEL_DISPLAY: {
573581
if (command instanceof StringType) {
574-
if (type == KebaType.P30 && (series == KebaSeries.C || series == KebaSeries.X)) {
575-
String cmd = command.toString();
576-
int maxLength = (cmd.length() < 23) ? cmd.length() : 23;
577-
transceiver.send("display 0 0 0 0 " + cmd.substring(0, maxLength), this);
578-
} else {
579-
logger.warn("'Display' is not supported on a KEBA KeContact {}:{}", type, series);
580-
}
582+
setDisplay(command.toString(), -1, -1);
581583
}
582584
break;
583585
}
@@ -602,4 +604,21 @@ public void handleCommand(ChannelUID channelUID, Command command) {
602604
}
603605
}
604606
}
607+
608+
public void setDisplay(String text, int durationMin, int durationMax) {
609+
if (type == KebaType.P30 && (series == KebaSeries.C || series == KebaSeries.X)) {
610+
int maxLength = (text.length() < 23) ? text.length() : 23;
611+
int a = 1;
612+
if (durationMax < 0 || durationMax < 0) {
613+
a = 0;
614+
durationMin = 0;
615+
durationMax = 0;
616+
}
617+
transceiver.send(
618+
"display " + a + " " + durationMin + " " + durationMax + " 0 " + text.substring(0, maxLength),
619+
this);
620+
} else {
621+
logger.warn("'Display' is not supported on a KEBA KeContact {}:{}", type, series);
622+
}
623+
}
605624
}

bundles/org.openhab.binding.keba/src/main/resources/OH-INF/i18n/keba.properties

+10
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,13 @@ channel-type.keba.x1.label = X1
9090
channel-type.keba.x1.description = State of the X1 input
9191
channel-type.keba.x2.label = X2
9292
channel-type.keba.x2.description = State of the X2 output
93+
94+
# thing actions
95+
actionLabel = set text in display
96+
actionDesc = Sets a text to show in the display of the wallbox
97+
actionInputTextLabel = Text
98+
actionInputTextDesc = Text shown on the display. Maximum 23 ASCII characters can be used. ~ == \u03A3, $ == blank, == comma
99+
actionInputDurationMinLabel = Duration (min)
100+
actionInputDurationMinDesc = Defines the duration in seconds how long the text will displayed before another display command will be processed (internal MID metering relevant information may overrule this).
101+
actionInputDurationMaxLabel = Duration (max)
102+
actionInputDurationMaxDesc = Defines the duration in seconds how long the text will displayed if no additional display command follows.

0 commit comments

Comments
 (0)