[boschindego] Add localization support for textual states (#12949)

* Add support for localization of textualstate texts
* Refactor state texts to eliminate redundancy

Fixes #12941

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2022-06-19 14:07:26 +02:00 committed by GitHub
parent daea9ae5b2
commit efb1bfc772
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 164 additions and 93 deletions

View 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;

View File

@ -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;
}
}

View File

@ -29,43 +29,46 @@ import org.openhab.binding.boschindego.internal.dto.DeviceCommand;
@NonNullByDefault
public class DeviceStatus {
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 final static String STATE_PREFIX = "indego.state.";
private final static String STATE_UNKNOWN = "unknown";
private String message;
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 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() {

View 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) {

View 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

View File

@ -53,36 +53,36 @@
<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>