]> git.basschouten.com Git - openhab-addons.git/commitdiff
[boschindego] Add localization support for textual states (#12949)
authorJacob Laursen <jacob-github@vindvejr.dk>
Sun, 19 Jun 2022 12:07:26 +0000 (14:07 +0200)
committerGitHub <noreply@github.com>
Sun, 19 Jun 2022 12:07:26 +0000 (14:07 +0200)
* Add support for localization of textualstate texts
* Refactor state texts to eliminate redundancy

Fixes #12941

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoHandlerFactory.java
bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoTranslationProvider.java [new file with mode: 0644]
bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/DeviceStatus.java
bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java
bundles/org.openhab.binding.boschindego/src/main/resources/OH-INF/i18n/boschindego.properties
bundles/org.openhab.binding.boschindego/src/main/resources/OH-INF/thing/thing-types.xml

index de97ac1fd98b1dbc753055bf6b538f0acf873959..4cb385d89235976229e0e963977a52b2214bbf70 100644 (file)
@@ -18,6 +18,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jetty.client.HttpClient;
 import org.openhab.binding.boschindego.internal.handler.BoschIndegoHandler;
+import org.openhab.core.i18n.LocaleProvider;
+import org.openhab.core.i18n.TranslationProvider;
 import org.openhab.core.io.net.http.HttpClientFactory;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingTypeUID;
@@ -40,12 +42,15 @@ import org.osgi.service.component.annotations.Reference;
 public class BoschIndegoHandlerFactory extends BaseThingHandlerFactory {
 
     private final HttpClient httpClient;
+    private final BoschIndegoTranslationProvider translationProvider;
 
     @Activate
     public BoschIndegoHandlerFactory(@Reference HttpClientFactory httpClientFactory,
+            final @Reference TranslationProvider i18nProvider, final @Reference LocaleProvider localeProvider,
             ComponentContext componentContext) {
         super.activate(componentContext);
         this.httpClient = httpClientFactory.getCommonHttpClient();
+        this.translationProvider = new BoschIndegoTranslationProvider(i18nProvider, localeProvider);
     }
 
     @Override
@@ -58,7 +63,7 @@ public class BoschIndegoHandlerFactory extends BaseThingHandlerFactory {
         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
 
         if (THING_TYPE_INDEGO.equals(thingTypeUID)) {
-            return new BoschIndegoHandler(thing, httpClient);
+            return new BoschIndegoHandler(thing, httpClient, translationProvider);
         }
 
         return null;
diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoTranslationProvider.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoTranslationProvider.java
new file mode 100644 (file)
index 0000000..7af1700
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.boschindego.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.i18n.LocaleProvider;
+import org.openhab.core.i18n.TranslationProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * {@link BoschIndegoTranslationProvider} provides i18n message lookup.
+ * 
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+public class BoschIndegoTranslationProvider {
+
+    private final Bundle bundle;
+    private final TranslationProvider i18nProvider;
+    private final LocaleProvider localeProvider;
+
+    public BoschIndegoTranslationProvider(TranslationProvider i18nProvider, LocaleProvider localeProvider) {
+        this.bundle = FrameworkUtil.getBundle(this.getClass());
+        this.i18nProvider = i18nProvider;
+        this.localeProvider = localeProvider;
+    }
+
+    public @Nullable String getText(String key, @Nullable Object... arguments) {
+        return i18nProvider.getText(bundle, key, null, localeProvider.getLocale(), arguments);
+    }
+
+    public String getText(String key, String defaultText, @Nullable Object... arguments) {
+        String text = i18nProvider.getText(bundle, key, defaultText, localeProvider.getLocale(), arguments);
+        if (text == null) {
+            return defaultText;
+        }
+        return text;
+    }
+}
index b4a85e58d1c8c157fcbc6ed92013100b3df3b5b8..2000ae8b51b63dcb140bf0c253b113e60d3cea64 100644 (file)
@@ -29,43 +29,46 @@ import org.openhab.binding.boschindego.internal.dto.DeviceCommand;
 @NonNullByDefault
 public class DeviceStatus {
 
+    private final static String STATE_PREFIX = "indego.state.";
+    private final static String STATE_UNKNOWN = "unknown";
+
     private static final Map<Integer, DeviceStatus> STATUS_MAP = Map.ofEntries(
-            entry(0, new DeviceStatus("Reading status", false, DeviceCommand.RETURN)),
-            entry(257, new DeviceStatus("Charging", false, DeviceCommand.RETURN)),
-            entry(258, new DeviceStatus("Docked", true, DeviceCommand.RETURN)),
-            entry(259, new DeviceStatus("Docked - Software update", false, DeviceCommand.RETURN)),
-            entry(260, new DeviceStatus("Docked", true, DeviceCommand.RETURN)),
-            entry(261, new DeviceStatus("Docked", true, DeviceCommand.RETURN)),
-            entry(262, new DeviceStatus("Docked - Loading map", false, DeviceCommand.MOW)),
-            entry(263, new DeviceStatus("Docked - Saving map", false, DeviceCommand.RETURN)),
-            entry(513, new DeviceStatus("Mowing", false, DeviceCommand.MOW)),
-            entry(514, new DeviceStatus("Relocalising", false, DeviceCommand.MOW)),
-            entry(515, new DeviceStatus("Loading map", false, DeviceCommand.MOW)),
-            entry(516, new DeviceStatus("Learning lawn", false, DeviceCommand.MOW)),
-            entry(517, new DeviceStatus("Paused", true, DeviceCommand.PAUSE)),
-            entry(518, new DeviceStatus("Border cut", false, DeviceCommand.MOW)),
-            entry(519, new DeviceStatus("Idle in lawn", true, DeviceCommand.MOW)),
-            entry(769, new DeviceStatus("Returning to dock", false, DeviceCommand.RETURN)),
-            entry(770, new DeviceStatus("Returning to dock", false, DeviceCommand.RETURN)),
-            entry(771, new DeviceStatus("Returning to dock - Battery low", false, DeviceCommand.RETURN)),
-            entry(772, new DeviceStatus("Returning to dock - Calendar timeslot ended", false, DeviceCommand.RETURN)),
-            entry(773, new DeviceStatus("Returning to dock - Battery temp range", false, DeviceCommand.RETURN)),
-            entry(774, new DeviceStatus("Returning to dock", false, DeviceCommand.RETURN)),
-            entry(775, new DeviceStatus("Returning to dock - Lawn complete", false, DeviceCommand.RETURN)),
-            entry(776, new DeviceStatus("Returning to dock - Relocalising", false, DeviceCommand.RETURN)),
-            entry(1025, new DeviceStatus("Diagnostic mode", false, null)),
-            entry(1026, new DeviceStatus("End of life", false, null)),
-            entry(1281, new DeviceStatus("Software update", false, null)),
-            entry(64513, new DeviceStatus("Docked", true, DeviceCommand.RETURN)));
-
-    private String message;
+            entry(0, new DeviceStatus("reading-status", false, DeviceCommand.RETURN)),
+            entry(257, new DeviceStatus("charging", false, DeviceCommand.RETURN)),
+            entry(258, new DeviceStatus("docked", true, DeviceCommand.RETURN)),
+            entry(259, new DeviceStatus("docked-software-update", false, DeviceCommand.RETURN)),
+            entry(260, new DeviceStatus("docked", true, DeviceCommand.RETURN)),
+            entry(261, new DeviceStatus("docked", true, DeviceCommand.RETURN)),
+            entry(262, new DeviceStatus("docked-loading-map", false, DeviceCommand.MOW)),
+            entry(263, new DeviceStatus("docked-saving-map", false, DeviceCommand.RETURN)),
+            entry(513, new DeviceStatus("mowing", false, DeviceCommand.MOW)),
+            entry(514, new DeviceStatus("relocalising", false, DeviceCommand.MOW)),
+            entry(515, new DeviceStatus("loading-map", false, DeviceCommand.MOW)),
+            entry(516, new DeviceStatus("learning-lawn", false, DeviceCommand.MOW)),
+            entry(517, new DeviceStatus("paused", true, DeviceCommand.PAUSE)),
+            entry(518, new DeviceStatus("border-cut", false, DeviceCommand.MOW)),
+            entry(519, new DeviceStatus("idle-in-lawn", true, DeviceCommand.MOW)),
+            entry(769, new DeviceStatus("returning-to-dock", false, DeviceCommand.RETURN)),
+            entry(770, new DeviceStatus("returning-to-dock", false, DeviceCommand.RETURN)),
+            entry(771, new DeviceStatus("returning-to-dock-battery-low", false, DeviceCommand.RETURN)),
+            entry(772, new DeviceStatus("returning-to-dock-calendar-timeslot-ended", false, DeviceCommand.RETURN)),
+            entry(773, new DeviceStatus("returning-to-dock-battery-temp-range", false, DeviceCommand.RETURN)),
+            entry(774, new DeviceStatus("returning-to-dock", false, DeviceCommand.RETURN)),
+            entry(775, new DeviceStatus("returning-to-dock-lawn-complete", false, DeviceCommand.RETURN)),
+            entry(776, new DeviceStatus("returning-to-dock-relocalising", false, DeviceCommand.RETURN)),
+            entry(1025, new DeviceStatus("diagnostic-mode", false, null)),
+            entry(1026, new DeviceStatus("end-of-life", false, null)),
+            entry(1281, new DeviceStatus("software-update", false, null)),
+            entry(64513, new DeviceStatus("docked", true, DeviceCommand.RETURN)));
+
+    private String textKey;
 
     private boolean isReadyToMow;
 
     private @Nullable DeviceCommand associatedCommand;
 
-    private DeviceStatus(String message, boolean isReadyToMow, @Nullable DeviceCommand associatedCommand) {
-        this.message = message;
+    private DeviceStatus(String textKey, boolean isReadyToMow, @Nullable DeviceCommand associatedCommand) {
+        this.textKey = textKey;
         this.isReadyToMow = isReadyToMow;
         this.associatedCommand = associatedCommand;
     }
@@ -95,11 +98,21 @@ public class DeviceStatus {
                 break;
         }
 
-        return new DeviceStatus(String.format("Unknown status code %d", code), false, command);
+        return new DeviceStatus(String.valueOf(code), false, command);
     }
 
-    public String getMessage() {
-        return message;
+    /**
+     * Returns a localized description for this {@link DeviceStatus}.
+     * 
+     * @param translationProvider
+     * @return localized status description
+     */
+    public String getMessage(BoschIndegoTranslationProvider translationProvider) {
+        String textualState = translationProvider.getText(STATE_PREFIX + textKey);
+        if (textualState == null) {
+            textualState = String.format(translationProvider.getText(STATE_PREFIX + STATE_UNKNOWN, textKey), textKey);
+        }
+        return textualState;
     }
 
     public boolean isReadyToMow() {
index 868e1be56f03a38312aa9767a2d1d63dfe98fea3..c3d9afa3268167c61deb221814a64231e0a16d7f 100644 (file)
@@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jetty.client.HttpClient;
+import org.openhab.binding.boschindego.internal.BoschIndegoTranslationProvider;
 import org.openhab.binding.boschindego.internal.DeviceStatus;
 import org.openhab.binding.boschindego.internal.IndegoController;
 import org.openhab.binding.boschindego.internal.config.BoschIndegoConfiguration;
@@ -53,15 +54,17 @@ public class BoschIndegoHandler extends BaseThingHandler {
 
     private final Logger logger = LoggerFactory.getLogger(BoschIndegoHandler.class);
     private final HttpClient httpClient;
+    private final BoschIndegoTranslationProvider translationProvider;
 
     private @NonNullByDefault({}) IndegoController controller;
     private @Nullable ScheduledFuture<?> pollFuture;
     private long refreshRate;
     private boolean propertiesInitialized;
 
-    public BoschIndegoHandler(Thing thing, HttpClient httpClient) {
+    public BoschIndegoHandler(Thing thing, HttpClient httpClient, BoschIndegoTranslationProvider translationProvider) {
         super(thing);
         this.httpClient = httpClient;
+        this.translationProvider = translationProvider;
     }
 
     @Override
@@ -178,7 +181,7 @@ public class BoschIndegoHandler extends BaseThingHandler {
         updateState(ERRORCODE, new DecimalType(error));
         updateState(MOWED, new PercentType(mowed));
         updateState(STATE, new DecimalType(status));
-        updateState(TEXTUAL_STATE, new StringType(deviceStatus.getMessage()));
+        updateState(TEXTUAL_STATE, new StringType(deviceStatus.getMessage(translationProvider)));
     }
 
     private boolean isReadyToMow(DeviceStatus deviceStatus, int error) {
index d665f90338b8292c0492e0afba6d86ead6fddcee..7522b02800611d23ee8ecd8de97f31984c043d50 100644 (file)
@@ -31,34 +31,7 @@ channel-type.boschindego.state.state.option.1 = Mow
 channel-type.boschindego.state.state.option.2 = Charge/Dock
 channel-type.boschindego.state.state.option.3 = Pause
 channel-type.boschindego.statecode.label = State Code
-channel-type.boschindego.statecode.description = API-code of the Indego state
-channel-type.boschindego.statecode.state.option.0 = Reading status
-channel-type.boschindego.statecode.state.option.257 = Charging
-channel-type.boschindego.statecode.state.option.258 = Docked
-channel-type.boschindego.statecode.state.option.259 = Docked - Software update
-channel-type.boschindego.statecode.state.option.260 = Docked
-channel-type.boschindego.statecode.state.option.261 = Docked
-channel-type.boschindego.statecode.state.option.262 = Docked - Loading map
-channel-type.boschindego.statecode.state.option.263 = Docked - Saving map
-channel-type.boschindego.statecode.state.option.512 = Mowing
-channel-type.boschindego.statecode.state.option.514 = Relocalising
-channel-type.boschindego.statecode.state.option.515 = Loading map
-channel-type.boschindego.statecode.state.option.516 = Learning lawn
-channel-type.boschindego.statecode.state.option.517 = Paused
-channel-type.boschindego.statecode.state.option.518 = Border cut
-channel-type.boschindego.statecode.state.option.519 = Idle in lawn
-channel-type.boschindego.statecode.state.option.769 = Returning to Dock
-channel-type.boschindego.statecode.state.option.770 = Returning to Dock
-channel-type.boschindego.statecode.state.option.771 = Returning to Dock - Battery low
-channel-type.boschindego.statecode.state.option.772 = Returning to Dock - Calendar timeslot ended
-channel-type.boschindego.statecode.state.option.773 = Returning to Dock - Battery temp range
-channel-type.boschindego.statecode.state.option.774 = Returning to Dock
-channel-type.boschindego.statecode.state.option.775 = Returning to Dock - Lawn complete
-channel-type.boschindego.statecode.state.option.776 = Returning to Dock - Relocalising
-channel-type.boschindego.statecode.state.option.1025 = Diagnostic mode
-channel-type.boschindego.statecode.state.option.1026 = End of life
-channel-type.boschindego.statecode.state.option.1281 = Software update
-channel-type.boschindego.statecode.state.option.64513 = Docked
+channel-type.boschindego.statecode.description = API code of the Indego state
 channel-type.boschindego.textualstate.label = Textual State
 
 # thing status descriptions
@@ -66,3 +39,29 @@ channel-type.boschindego.textualstate.label = Textual State
 offline.comm-error.authentication-failure = The login credentials are wrong or another client is connected to your Indego account
 offline.conf-error.missing-password = Password missing
 offline.conf-error.missing-username = Username missing
+
+# indego states
+
+indego.state.unknown = Unknown status code: %s
+indego.state.reading-status = Reading status
+indego.state.charging = Charging
+indego.state.docked = Docked
+indego.state.docked-software-update = Docked - Software update
+indego.state.docked-loading-map = Docked - Loading map
+indego.state.docked-saving-map = Docked - Saving map
+indego.state.mowing = Mowing
+indego.state.relocalising = Relocalising
+indego.state.loading-map = Loading map
+indego.state.learning-lawn = Learning lawn
+indego.state.paused = Paused
+indego.state.border-cut = Border cut
+indego.state.idle-in-lawn = Idle in lawn
+indego.state.returning-to-dock = Returning to Dock
+indego.state.returning-to-dock-battery-low = Returning to Dock - Battery low
+indego.state.returning-to-dock-calendar-timeslot-ended = Calendar timeslot ended
+indego.state.returning-to-dock-battery-temp-range = Returning to Dock - Battery temp range
+indego.state.returning-to-dock-lawn-complete = Returning to Dock - Lawn complete
+indego.state.returning-to-dock-relocalising = Returning to Dock - Relocalising
+indego.state.diagnostic-mode = Diagnostic mode
+indego.state.end-of-life = End of life
+indego.state.software-update = Software update
index 7faeacbda86850e9a195b0094232940249e595d9..487884378a9e616415e438dda2f41499e49fe5d5 100644 (file)
        <channel-type id="statecode" advanced="true">
                <item-type>Number</item-type>
                <label>State Code</label>
-               <description>API-code of the Indego state</description>
+               <description>API code of the Indego state</description>
                <state readOnly="true">
                        <options>
-                               <option value="0">Reading status</option>
-                               <option value="257">Charging</option>
-                               <option value="258">Docked</option>
-                               <option value="259">Docked - Software update</option>
-                               <option value="260">Docked</option>
-                               <option value="261">Docked</option>
-                               <option value="262">Docked - Loading map</option>
-                               <option value="263">Docked - Saving map</option>
-                               <option value="512">Mowing</option>
-                               <option value="514">Relocalising</option>
-                               <option value="515">Loading map</option>
-                               <option value="516">Learning lawn</option>
-                               <option value="517">Paused</option>
-                               <option value="518">Border cut</option>
-                               <option value="519">Idle in lawn</option>
-                               <option value="769">Returning to Dock</option>
-                               <option value="770">Returning to Dock</option>
-                               <option value="771">Returning to Dock - Battery low</option>
-                               <option value="772">Returning to Dock - Calendar timeslot ended</option>
-                               <option value="773">Returning to Dock - Battery temp range</option>
-                               <option value="774">Returning to Dock</option>
-                               <option value="775">Returning to Dock - Lawn complete</option>
-                               <option value="776">Returning to Dock - Relocalising</option>
-                               <option value="1025">Diagnostic mode</option>
-                               <option value="1026">End of life</option>
-                               <option value="1281">Software update</option>
-                               <option value="64513">Docked</option>
+                               <option value="0">@text/indego.state.reading-status</option>
+                               <option value="257">@text/indego.state.charging</option>
+                               <option value="258">@text/indego.state.docked</option>
+                               <option value="259">@text/indego.state.docked-software-update</option>
+                               <option value="260">@text/indego.state.docked</option>
+                               <option value="261">@text/indego.state.docked</option>
+                               <option value="262">@text/indego.state.docked-loading-map</option>
+                               <option value="263">@text/indego.state.docked-saving-map</option>
+                               <option value="512">@text/indego.state.mowing</option>
+                               <option value="514">@text/indego.state.relocalising</option>
+                               <option value="515">@text/indego.state.loading-map</option>
+                               <option value="516">@text/indego.state.learning-lawn</option>
+                               <option value="517">@text/indego.state.paused</option>
+                               <option value="518">@text/indego.state.border-cut</option>
+                               <option value="519">@text/indego.state.idle-in-lawn</option>
+                               <option value="769">@text/indego.state.returning-to-dock</option>
+                               <option value="770">@text/indego.state.returning-to-dock</option>
+                               <option value="771">@text/indego.state.returning-to-dock-battery-low</option>
+                               <option value="772">@text/indego.state.returning-to-dock-calendar-timeslot-ended</option>
+                               <option value="773">@text/indego.state.returning-to-dock-battery-temp-range</option>
+                               <option value="774">@text/indego.state.returning-to-dock</option>
+                               <option value="775">@text/indego.state.returning-to-dock-lawn-complete</option>
+                               <option value="776">@text/indego.state.returning-to-dock-relocalising</option>
+                               <option value="1025">@text/indego.state.diagnostic-mode</option>
+                               <option value="1026">@text/indego.state.end-of-life</option>
+                               <option value="1281">@text/indego.state.software-update</option>
+                               <option value="64513">@text/indego.state.docked</option>
                        </options>
                </state>
        </channel-type>