[Sagercaster] Reintroducing timestamp channel (#11665)
[Sagercaster] Reintroducing timestamp channel Signed-off-by: clinique <gael@lhopital.org>pull/11706/head
parent
13bae622ac
commit
4605edeb29
|
@ -6,7 +6,8 @@ The Sager Weathercaster is a scientific instrument for accurate prediction of th
|
|||
|
||||
* To operate, this binding will need to use channel values provided by other means (e.g. Weather Binding, Netatmo, a 1-Wire personal weather station...)
|
||||
|
||||
* This binding buffers readings for some hours before producing weather forecasts(wind direction and sea level pressure). SagerWeatherCaster needs an observation period of minimum 6 hours.
|
||||
* This binding buffers readings for some hours before producing weather forecasts(wind direction and sea level pressure).
|
||||
SagerWeatherCaster needs an observation period of minimum 6 hours.
|
||||
|
||||
For these reasons, this binding is not a binding in the usual sense.
|
||||
|
||||
|
@ -24,9 +25,11 @@ The binding itself does not require any configuration.
|
|||
|
||||
| Name | Type | Description |
|
||||
|--------------------|----------|--------------------------------------------------------------------------|
|
||||
| location | Location | Latitude and longitude of the desired weather forecast. |
|
||||
| location (*) | Location | Latitude and longitude of the desired weather forecast. |
|
||||
| observation-period | int | Minimum delay (in hours) before producing forecasts. Defaulted to 6. |
|
||||
|
||||
(*) Only latitude is used by the algorithm.
|
||||
|
||||
## Channels
|
||||
|
||||
The binding will use some input channels, that can be configured directly with profiles (sample below).
|
||||
|
@ -41,6 +44,8 @@ The binding will use some input channels, that can be configured directly with p
|
|||
| wind-speed-beaufort | input |Number | Wind speed expressed using the Beaufort scale |
|
||||
| pressure | input |Number:Pressure | Sea level pressure |
|
||||
| wind-angle | input |Number:Angle | Wind direction |
|
||||
| temperature | input |Number:Temperature | Outside temperature |
|
||||
| timestamp | output |DateTime | Timestamp of the last forecast update |
|
||||
| forecast | output |String | Description of the weather forecast |
|
||||
| velocity | output |String | Description of the expected wind evolution |
|
||||
| velocity-beaufort | output |Number | Expected wind evolution using the Beaufort scale |
|
||||
|
|
|
@ -48,6 +48,8 @@ public class SagerCasterBindingConstants {
|
|||
public static final String CHANNEL_WINDEVOLUTION = "wind-evolution";
|
||||
public static final String CHANNEL_PRESSURETREND = "pressure-trend";
|
||||
public static final String CHANNEL_TEMPERATURETREND = "temperature-trend";
|
||||
public static final String CHANNEL_TIMESTAMP = "timestamp";
|
||||
|
||||
// Input channel ids
|
||||
public static final String CHANNEL_CLOUDINESS = "cloudiness";
|
||||
public static final String CHANNEL_IS_RAINING = "is-raining";
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Set;
|
|||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.sagercaster.internal.caster.SagerWeatherCaster;
|
||||
import org.openhab.binding.sagercaster.internal.handler.SagerCasterHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2021 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.sagercaster.internal.caster;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* This class holds the result of the SagerCaster algorithm
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SagerPrediction {
|
||||
private final String prediction;
|
||||
|
||||
public SagerPrediction(String sagerCode) {
|
||||
this.prediction = sagerCode;
|
||||
}
|
||||
|
||||
public String getSagerCode() {
|
||||
return prediction;
|
||||
}
|
||||
|
||||
public String getForecast() {
|
||||
return Character.toString(prediction.charAt(0));
|
||||
}
|
||||
|
||||
public String getWindVelocity() {
|
||||
return Character.toString(prediction.charAt(1));
|
||||
}
|
||||
|
||||
public String getWindDirection() {
|
||||
return Character.toString(prediction.charAt(2));
|
||||
}
|
||||
|
||||
public String getWindDirection2() {
|
||||
return prediction.length() > 3 ? Character.toString(prediction.charAt(3)) : SagerWeatherCaster.UNDEF;
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@
|
|||
* 378 possible forecasts determined from 4996 dial codes.
|
||||
*/
|
||||
|
||||
package org.openhab.binding.sagercaster.internal;
|
||||
package org.openhab.binding.sagercaster.internal.caster;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -76,6 +76,7 @@ import org.slf4j.LoggerFactory;
|
|||
@Component(service = SagerWeatherCaster.class, scope = ServiceScope.SINGLETON)
|
||||
@NonNullByDefault
|
||||
public class SagerWeatherCaster {
|
||||
public final static String UNDEF = "-";
|
||||
// Northern Polar Zone & Northern Tropical Zone
|
||||
private final static String[] NPZDIRECTIONS = { "S", "SW", "W", "NW", "N", "NE", "E", "SE" };
|
||||
// Northern Temperate Zone
|
||||
|
@ -88,7 +89,7 @@ public class SagerWeatherCaster {
|
|||
private final Logger logger = LoggerFactory.getLogger(SagerWeatherCaster.class);
|
||||
private final Properties forecaster = new Properties();
|
||||
|
||||
private Optional<Prevision> prevision = Optional.empty();
|
||||
private Optional<SagerPrediction> prevision = Optional.empty();
|
||||
private String[] usedDirections = NTZDIRECTIONS; // Defaulted to Northern Zone
|
||||
|
||||
private int currentBearing = -1;
|
||||
|
@ -238,7 +239,7 @@ public class SagerWeatherCaster {
|
|||
|
||||
private void updatePrediction() {
|
||||
int zWind = Arrays.asList(usedDirections).indexOf(getCompass());
|
||||
String d1 = "-";
|
||||
String d1 = UNDEF;
|
||||
switch (zWind) {
|
||||
case 0:
|
||||
if (windEvolution == 3) {
|
||||
|
@ -319,39 +320,27 @@ public class SagerWeatherCaster {
|
|||
}
|
||||
String forecast = forecaster.getProperty(
|
||||
d1 + String.valueOf(sagerPressure) + String.valueOf(pressureEvolution) + String.valueOf(nubes));
|
||||
prevision = (forecast != null) ? Optional.of(new Prevision(forecast)) : Optional.empty();
|
||||
prevision = Optional.ofNullable(forecast != null ? new SagerPrediction(forecast) : null);
|
||||
}
|
||||
|
||||
public String getForecast() {
|
||||
if (prevision.isPresent()) {
|
||||
char forecast = prevision.get().zForecast;
|
||||
return Character.toString(forecast);
|
||||
}
|
||||
return "-";
|
||||
return prevision.map(p -> p.getForecast()).orElse(UNDEF);
|
||||
}
|
||||
|
||||
public String getWindVelocity() {
|
||||
if (prevision.isPresent()) {
|
||||
char windVelocity = prevision.get().zWindVelocity;
|
||||
return Character.toString(windVelocity);
|
||||
}
|
||||
return "-";
|
||||
return prevision.map(p -> p.getWindVelocity()).orElse(UNDEF);
|
||||
}
|
||||
|
||||
public String getWindDirection() {
|
||||
if (prevision.isPresent()) {
|
||||
int direction = prevision.get().zWindDirection;
|
||||
return String.valueOf(direction);
|
||||
}
|
||||
return "-";
|
||||
return prevision.map(p -> p.getWindDirection()).orElse(UNDEF);
|
||||
}
|
||||
|
||||
public String getWindDirection2() {
|
||||
if (prevision.isPresent()) {
|
||||
int direction = prevision.get().zWindDirection2;
|
||||
return String.valueOf(direction);
|
||||
return prevision.map(p -> p.getWindDirection2()).orElse(UNDEF);
|
||||
}
|
||||
return "-";
|
||||
|
||||
public String getSagerCode() {
|
||||
return prevision.map(p -> p.getSagerCode()).orElse(UNDEF);
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
|
@ -370,17 +359,31 @@ public class SagerWeatherCaster {
|
|||
}
|
||||
}
|
||||
|
||||
private class Prevision {
|
||||
public final char zForecast;
|
||||
public final char zWindVelocity;
|
||||
public final int zWindDirection;
|
||||
public final int zWindDirection2;
|
||||
|
||||
public Prevision(String forecast) {
|
||||
zForecast = forecast.charAt(0);
|
||||
zWindVelocity = forecast.charAt(1);
|
||||
zWindDirection = Character.getNumericValue(forecast.charAt(2));
|
||||
zWindDirection2 = (forecast.length() > 3) ? Character.getNumericValue(forecast.charAt(3)) : -1;
|
||||
}
|
||||
public int getPredictedBeaufort() {
|
||||
int result = currentBeaufort;
|
||||
switch (getWindVelocity()) {
|
||||
case "N":
|
||||
result += 1;
|
||||
break;
|
||||
case "F":
|
||||
result = 4;
|
||||
break;
|
||||
case "S":
|
||||
result = 6;
|
||||
break;
|
||||
case "G":
|
||||
result = 8;
|
||||
break;
|
||||
case "W":
|
||||
result = 10;
|
||||
break;
|
||||
case "H":
|
||||
result = 12;
|
||||
break;
|
||||
case "D":
|
||||
result -= 1;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -16,9 +16,9 @@ import static org.openhab.binding.sagercaster.internal.SagerCasterBindingConstan
|
|||
import static org.openhab.core.library.unit.MetricPrefix.HECTO;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.measure.quantity.Angle;
|
||||
|
@ -26,8 +26,9 @@ import javax.measure.quantity.Pressure;
|
|||
import javax.measure.quantity.Temperature;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.sagercaster.internal.SagerWeatherCaster;
|
||||
import org.openhab.binding.sagercaster.internal.WindDirectionStateDescriptionProvider;
|
||||
import org.openhab.binding.sagercaster.internal.caster.SagerWeatherCaster;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
|
@ -36,6 +37,7 @@ import org.openhab.core.library.unit.SIUnits;
|
|||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
|
@ -58,11 +60,12 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
|
||||
private final WindDirectionStateDescriptionProvider stateDescriptionProvider;
|
||||
|
||||
private final ExpiringMap<QuantityType<Pressure>> pressureCache = new ExpiringMap<>();
|
||||
private final ExpiringMap<QuantityType<Temperature>> temperatureCache = new ExpiringMap<>();
|
||||
private final ExpiringMap<QuantityType<Angle>> bearingCache = new ExpiringMap<>();
|
||||
private final ExpiringMap<Double> pressureCache = new ExpiringMap<>();
|
||||
private final ExpiringMap<Double> temperatureCache = new ExpiringMap<>();
|
||||
private final ExpiringMap<Integer> bearingCache = new ExpiringMap<>();
|
||||
|
||||
private int currentTemp = 0;
|
||||
private double currentTemp = 0;
|
||||
private String currentSagerCode = SagerWeatherCaster.UNDEF;
|
||||
|
||||
public SagerCasterHandler(Thing thing, WindDirectionStateDescriptionProvider stateDescriptionProvider,
|
||||
SagerWeatherCaster sagerWeatherCaster) {
|
||||
|
@ -73,15 +76,17 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
String location = (String) getConfig().get(CONFIG_LOCATION);
|
||||
int observationPeriod = ((BigDecimal) getConfig().get(CONFIG_PERIOD)).intValue();
|
||||
String latitude = location.split(",")[0];
|
||||
sagerWeatherCaster.setLatitude(Double.parseDouble(latitude));
|
||||
long period = TimeUnit.HOURS.toMillis(observationPeriod);
|
||||
pressureCache.setObservationPeriod(period);
|
||||
bearingCache.setObservationPeriod(period);
|
||||
temperatureCache.setObservationPeriod(period);
|
||||
|
||||
String location = (String) getConfig().get(CONFIG_LOCATION);
|
||||
String latitude = location.split(",")[0];
|
||||
sagerWeatherCaster.setLatitude(Double.parseDouble(latitude));
|
||||
defineWindDirectionStateDescriptions();
|
||||
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
|
@ -95,10 +100,9 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
}
|
||||
|
||||
options.add(new StateOption("9", "Shifting / Variable winds"));
|
||||
stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), GROUP_OUTPUT, CHANNEL_WINDFROM),
|
||||
options);
|
||||
stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), GROUP_OUTPUT, CHANNEL_WINDTO),
|
||||
options);
|
||||
ThingUID thingUID = getThing().getUID();
|
||||
stateDescriptionProvider.setStateOptions(new ChannelUID(thingUID, GROUP_OUTPUT, CHANNEL_WINDFROM), options);
|
||||
stateDescriptionProvider.setStateOptions(new ChannelUID(thingUID, GROUP_OUTPUT, CHANNEL_WINDTO), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,7 +113,7 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
String id = channelUID.getIdWithoutGroup();
|
||||
switch (id) {
|
||||
case CHANNEL_CLOUDINESS:
|
||||
logger.debug("Octa cloud level changed, updating forecast");
|
||||
logger.debug("Cloud level changed, updating forecast");
|
||||
if (command instanceof QuantityType) {
|
||||
QuantityType<?> cloudiness = (QuantityType<?>) command;
|
||||
scheduler.submit(() -> {
|
||||
|
@ -127,26 +131,17 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
postNewForecast();
|
||||
});
|
||||
} else {
|
||||
logger.debug("Channel '{}' can only accept Switch type commands.", channelUID);
|
||||
logger.debug("Channel '{}' accepts Switch commands.", channelUID);
|
||||
}
|
||||
break;
|
||||
case CHANNEL_RAIN_QTTY:
|
||||
logger.debug("Rain status updated, updating forecast");
|
||||
if (command instanceof QuantityType) {
|
||||
QuantityType<?> newQtty = (QuantityType<?>) command;
|
||||
scheduler.submit(() -> {
|
||||
sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0);
|
||||
postNewForecast();
|
||||
});
|
||||
updateRain((QuantityType<?>) command);
|
||||
} else if (command instanceof DecimalType) {
|
||||
DecimalType newQtty = (DecimalType) command;
|
||||
scheduler.submit(() -> {
|
||||
sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0);
|
||||
postNewForecast();
|
||||
});
|
||||
updateRain((DecimalType) command);
|
||||
} else {
|
||||
logger.debug("Channel '{}' can accept Number, Number:Speed, Number:Length type commands.",
|
||||
channelUID);
|
||||
logger.debug("Channel '{}' accepts Number, Number:(Speed|Length) commands.", channelUID);
|
||||
}
|
||||
break;
|
||||
case CHANNEL_WIND_SPEED:
|
||||
|
@ -165,12 +160,13 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
logger.debug("Sea-level pressure updated, updating forecast");
|
||||
if (command instanceof QuantityType) {
|
||||
@SuppressWarnings("unchecked")
|
||||
QuantityType<Pressure> newPressure = ((QuantityType<Pressure>) command)
|
||||
QuantityType<Pressure> pressQtty = ((QuantityType<Pressure>) command)
|
||||
.toUnit(HECTO(SIUnits.PASCAL));
|
||||
if (newPressure != null) {
|
||||
pressureCache.put(newPressure);
|
||||
pressureCache.getAgedValue().ifPresentOrElse(pressure -> scheduler.submit(() -> {
|
||||
sagerWeatherCaster.setPressure(newPressure.doubleValue(), pressure.doubleValue());
|
||||
if (pressQtty != null) {
|
||||
double newPressureValue = pressQtty.doubleValue();
|
||||
pressureCache.put(newPressureValue);
|
||||
pressureCache.getAgedValue().ifPresentOrElse(oldPressure -> scheduler.submit(() -> {
|
||||
sagerWeatherCaster.setPressure(newPressureValue, oldPressure);
|
||||
updateChannelString(GROUP_OUTPUT, CHANNEL_PRESSURETREND,
|
||||
String.valueOf(sagerWeatherCaster.getPressureEvolution()));
|
||||
postNewForecast();
|
||||
|
@ -182,14 +178,13 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
logger.debug("Temperature updated");
|
||||
if (command instanceof QuantityType) {
|
||||
@SuppressWarnings("unchecked")
|
||||
QuantityType<Temperature> newTemperature = ((QuantityType<Temperature>) command)
|
||||
QuantityType<Temperature> tempQtty = ((QuantityType<Temperature>) command)
|
||||
.toUnit(SIUnits.CELSIUS);
|
||||
if (newTemperature != null) {
|
||||
temperatureCache.put(newTemperature);
|
||||
currentTemp = newTemperature.intValue();
|
||||
Optional<QuantityType<Temperature>> agedTemperature = temperatureCache.getAgedValue();
|
||||
agedTemperature.ifPresent(temperature -> {
|
||||
double delta = newTemperature.doubleValue() - temperature.doubleValue();
|
||||
if (tempQtty != null) {
|
||||
currentTemp = tempQtty.doubleValue();
|
||||
temperatureCache.put(currentTemp);
|
||||
temperatureCache.getAgedValue().ifPresent(oldTemperature -> {
|
||||
double delta = currentTemp - oldTemperature;
|
||||
String trend = (delta > 3) ? "1"
|
||||
: (delta > 0.3) ? "2" : (delta > -0.3) ? "3" : (delta > -3) ? "4" : "5";
|
||||
updateChannelString(GROUP_OUTPUT, CHANNEL_TEMPERATURETREND, trend);
|
||||
|
@ -201,12 +196,12 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
logger.debug("Updated wind direction, updating forecast");
|
||||
if (command instanceof QuantityType) {
|
||||
@SuppressWarnings("unchecked")
|
||||
QuantityType<Angle> newAngle = (QuantityType<Angle>) command;
|
||||
bearingCache.put(newAngle);
|
||||
Optional<QuantityType<Angle>> agedAngle = bearingCache.getAgedValue();
|
||||
agedAngle.ifPresent(angle -> {
|
||||
QuantityType<Angle> angleQtty = (QuantityType<Angle>) command;
|
||||
int newAngleValue = angleQtty.intValue();
|
||||
bearingCache.put(newAngleValue);
|
||||
bearingCache.getAgedValue().ifPresent(oldAngle -> {
|
||||
scheduler.submit(() -> {
|
||||
sagerWeatherCaster.setBearing(newAngle.intValue(), angle.intValue());
|
||||
sagerWeatherCaster.setBearing(newAngleValue, oldAngle);
|
||||
updateChannelString(GROUP_OUTPUT, CHANNEL_WINDEVOLUTION,
|
||||
String.valueOf(sagerWeatherCaster.getWindEvolution()));
|
||||
postNewForecast();
|
||||
|
@ -220,7 +215,19 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private void updateRain(Number newQtty) {
|
||||
scheduler.submit(() -> {
|
||||
sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0);
|
||||
postNewForecast();
|
||||
});
|
||||
}
|
||||
|
||||
private void postNewForecast() {
|
||||
String newSagerCode = sagerWeatherCaster.getSagerCode();
|
||||
if (!newSagerCode.equals(currentSagerCode)) {
|
||||
logger.debug("Sager prediction changed to {}", newSagerCode);
|
||||
currentSagerCode = newSagerCode;
|
||||
updateChannelTimeStamp(GROUP_OUTPUT, CHANNEL_TIMESTAMP, ZonedDateTime.now());
|
||||
String forecast = sagerWeatherCaster.getForecast();
|
||||
// Sharpens forecast if current temp is below 2 degrees, likely to be flurries rather than shower
|
||||
forecast += SHOWERS.contains(forecast) ? (currentTemp > 2) ? "1" : "2" : "";
|
||||
|
@ -228,34 +235,16 @@ public class SagerCasterHandler extends BaseThingHandler {
|
|||
updateChannelString(GROUP_OUTPUT, CHANNEL_FORECAST, forecast);
|
||||
updateChannelString(GROUP_OUTPUT, CHANNEL_WINDFROM, sagerWeatherCaster.getWindDirection());
|
||||
updateChannelString(GROUP_OUTPUT, CHANNEL_WINDTO, sagerWeatherCaster.getWindDirection2());
|
||||
|
||||
String velocity = sagerWeatherCaster.getWindVelocity();
|
||||
updateChannelString(GROUP_OUTPUT, CHANNEL_VELOCITY, velocity);
|
||||
int predictedBeaufort = sagerWeatherCaster.getBeaufort();
|
||||
switch (velocity) {
|
||||
case "N":
|
||||
predictedBeaufort += 1;
|
||||
break;
|
||||
case "F":
|
||||
predictedBeaufort = 4;
|
||||
break;
|
||||
case "S":
|
||||
predictedBeaufort = 6;
|
||||
break;
|
||||
case "G":
|
||||
predictedBeaufort = 8;
|
||||
break;
|
||||
case "W":
|
||||
predictedBeaufort = 10;
|
||||
break;
|
||||
case "H":
|
||||
predictedBeaufort = 12;
|
||||
break;
|
||||
case "D":
|
||||
predictedBeaufort -= 1;
|
||||
break;
|
||||
updateChannelString(GROUP_OUTPUT, CHANNEL_VELOCITY, sagerWeatherCaster.getWindVelocity());
|
||||
updateChannelDecimal(GROUP_OUTPUT, CHANNEL_VELOCITY_BEAUFORT, sagerWeatherCaster.getPredictedBeaufort());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateChannelTimeStamp(String group, String channelId, ZonedDateTime zonedDateTime) {
|
||||
ChannelUID id = new ChannelUID(getThing().getUID(), group, channelId);
|
||||
if (isLinked(id)) {
|
||||
updateState(id, new DateTimeType(zonedDateTime));
|
||||
}
|
||||
updateChannelDecimal(GROUP_OUTPUT, CHANNEL_VELOCITY_BEAUFORT, predictedBeaufort);
|
||||
}
|
||||
|
||||
private void updateChannelString(String group, String channelId, String value) {
|
||||
|
|
|
@ -43,6 +43,8 @@ rainingDescription = Is it currently raining ?
|
|||
beaufortLabel = Beaufort
|
||||
beaufortDescription = Wind speed using Beaufort Scale
|
||||
pressureDescription = Barometric pressure at sea level.
|
||||
timestampChannelLabel = Timestamp
|
||||
timestampChannelDescription = Timestamp of the last weather forecast update.
|
||||
|
||||
# channel options
|
||||
forecast0 = Not enough historic data to study pressure evolution, wait a bit ...
|
||||
|
@ -52,33 +54,33 @@ forecastC = Fair and cooler
|
|||
forecastD = Unsettled
|
||||
forecastE = Unsettled and warmer
|
||||
forecastF = Unsettled and cooler
|
||||
forecastG = Increasing cloudiness or overcast followed by Precipitation or showers/Flurries
|
||||
forecastG1 = Increasing cloudiness or overcast followed by Precipitation or showers
|
||||
forecastG2 = Increasing cloudiness or overcast followed by Precipitation or Flurries
|
||||
forecastH = Increasing cloudiness or overcast followed by Precipitation or showers and warmer
|
||||
forecastG = Increasing cloudiness or overcast followed by precipitation or showers/flurries
|
||||
forecastG1 = Increasing cloudiness or overcast followed by precipitation or showers
|
||||
forecastG2 = Increasing cloudiness or overcast followed by precipitation or flurries
|
||||
forecastH = Increasing cloudiness or overcast followed by precipitation or showers and warmer
|
||||
forecastJ = Showers
|
||||
forecastK = Showers/Flurries and warmer
|
||||
forecastK = Showers/flurries and warmer
|
||||
forecastK1 = Showers and warmer
|
||||
forecastK2 = Flurries and warmer
|
||||
forecastL = Showers/Flurries and cooler
|
||||
forecastL = Showers/flurries and cooler
|
||||
forecastL1 = Showers and cooler
|
||||
forecastL2 = Flurries and cooler
|
||||
forecastM = Precipitation
|
||||
forecastN = Precipitation and warmer
|
||||
forecastP = Precipitation and turning cooler; then improvement likely in 24 hours
|
||||
forecastR = Precipitation or showers/Flurries followed by improvement (within 12 hours)
|
||||
forecastR = Precipitation or showers/flurries followed by improvement (within 12 hours)
|
||||
forecastR1 = Precipitation or showers followed by improvement (within 12 hours)
|
||||
forecastR2 = Precipitation or flurries followed by improvement (within 12 hours)
|
||||
forecastS = Precipitation or showers/Flurries followed by improvement (within 12 hours) and becoming cooler
|
||||
forecastS = Precipitation or showers/flurries followed by improvement (within 12 hours) and becoming cooler
|
||||
forecastS1 = Precipitation or showers followed by improvement (within 12 hours) and becoming cooler
|
||||
forecastS2 = Precipitation or flurries followed by improvement (within 12 hours) and becoming cooler
|
||||
forecastT = Precipitation or showers/Flurries followed by improvement early in period (within 6 hours)
|
||||
forecastT = Precipitation or showers/flurries followed by improvement early in period (within 6 hours)
|
||||
forecastT1 = Precipitation or showers followed by improvement early in period (within 6 hours)
|
||||
forecastT2 = Precipitation or flurries followed by improvement early in period (within 6 hours)
|
||||
forecastU = Precipitation or showers/Flurries by improvement early in period (within 6 hours) and becoming cooler
|
||||
forecastU = Precipitation or showers/flurries by improvement early in period (within 6 hours) and becoming cooler
|
||||
forecastU1 = Precipitation or showers by improvement early in period (within 6 hours) and becoming cooler
|
||||
forecastU2 = Precipitation or flurries by improvement early in period (within 6 hours) and becoming cooler
|
||||
forecastW = Precipitation or showers/Flurries followed by fair early in period (within 6 hours) and becoming cooler
|
||||
forecastW = Precipitation or showers/flurries followed by fair early in period (within 6 hours) and becoming cooler
|
||||
forecastW1 = Precipitation or showers followed by fair early in period (within 6 hours) and becoming cooler
|
||||
forecastW2 = Precipitation or flurries followed by fair early in period (within 6 hours) and becoming cooler
|
||||
forecastX = Unsettled followed by fair
|
||||
|
|
|
@ -43,6 +43,8 @@ rainingDescription = Pleut-il actuellement ?
|
|||
beaufortLabel = Beaufort
|
||||
beaufortDescription = Force du vent mesurée sur l'échelle Beaufort
|
||||
pressureDescription = Pression barométrique au niveau de la mer.
|
||||
timestampChannelLabel = Horodatage
|
||||
timestampChannelDescription = Horodatage de la dernière mise à jour de la prévision météo.
|
||||
|
||||
# channel options
|
||||
forecast0 = Patientez encore un peu pour une prédiction
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
<label>@text/tempTrendLabel</label>
|
||||
<description>@text/tempTrendDescription</description>
|
||||
</channel>
|
||||
<channel id="timestamp" typeId="timestamp"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
|
@ -163,6 +164,7 @@
|
|||
<item-type>String</item-type>
|
||||
<label>@text/trendLabel</label>
|
||||
<description>@text/trendDescription</description>
|
||||
<category>Line</category>
|
||||
<state readOnly="true" pattern="%s">
|
||||
<options>
|
||||
<option value="1">@text/trend1</option>
|
||||
|
@ -174,19 +176,23 @@
|
|||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="timestamp" advanced="true">
|
||||
<channel-type id="timestamp">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>@text/timestampLabel</label>
|
||||
<description>@text/timestampDescription</description>
|
||||
<category>Observation time</category>
|
||||
<state readOnly="true"></state>
|
||||
<label>@text/timestampChannelLabel</label>
|
||||
<description>@text/timestampChannelDescription</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Timestamp</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="cloudiness">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>@text/cloudinessLabel</label>
|
||||
<description>@text/cloudinessDescription</description>
|
||||
<category>Clouds</category>
|
||||
<category>Sun_Clouds</category>
|
||||
<state min="0" max="100" pattern="%d %%"/>
|
||||
</channel-type>
|
||||
|
||||
|
|
Loading…
Reference in New Issue