[OpenUV] Correcting a SAT finding. (#8967)

* Correcting a SAT finding.
Adding alert levels compatible with MeteoAlarm and Vigicrues
* Adressing code review.
* spotless apply

Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
Gaël L'hopital 2020-11-09 17:55:35 +01:00 committed by GitHub
parent 8de5652ed1
commit 94245b627d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 35 deletions

View File

@ -39,6 +39,7 @@ public class OpenUVBindingConstants {
// List of all Channel id's // List of all Channel id's
public static final String UV_INDEX = "UVIndex"; public static final String UV_INDEX = "UVIndex";
public static final String ALERT_LEVEL = "Alert";
public static final String UV_COLOR = "UVColor"; public static final String UV_COLOR = "UVColor";
public static final String UV_MAX = "UVMax"; public static final String UV_MAX = "UVMax";
public static final String UV_MAX_TIME = "UVMaxTime"; public static final String UV_MAX_TIME = "UVMaxTime";

View File

@ -29,11 +29,16 @@ public class OpenUVException extends Exception {
super(message); super(message);
} }
private boolean checkMatches(String message) {
String currentMessage = getMessage();
return currentMessage != null && currentMessage.startsWith(message);
}
public boolean isApiKeyError() { public boolean isApiKeyError() {
return this.getMessage().startsWith(ERROR_WRONG_KEY); return checkMatches(ERROR_WRONG_KEY);
} }
public boolean isQuotaError() { public boolean isQuotaError() {
return this.getMessage().startsWith(ERROR_QUOTA_EXCEEDED); return checkMatches(ERROR_QUOTA_EXCEEDED);
} }
} }

View File

@ -22,7 +22,6 @@ import org.openhab.binding.openuv.internal.handler.OpenUVBridgeHandler;
import org.openhab.binding.openuv.internal.handler.OpenUVReportHandler; import org.openhab.binding.openuv.internal.handler.OpenUVReportHandler;
import org.openhab.core.i18n.LocationProvider; import org.openhab.core.i18n.LocationProvider;
import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingTypeUID;
@ -56,9 +55,6 @@ public class OpenUVHandlerFactory extends BaseThingHandlerFactory {
@Reference LocationProvider locationProvider) { @Reference LocationProvider locationProvider) {
this.locationProvider = locationProvider; this.locationProvider = locationProvider;
this.gson = new GsonBuilder() this.gson = new GsonBuilder()
.registerTypeAdapter(DecimalType.class,
(JsonDeserializer<DecimalType>) (json, type, jsonDeserializationContext) -> DecimalType
.valueOf(json.getAsJsonPrimitive().getAsString()))
.registerTypeAdapter(ZonedDateTime.class, .registerTypeAdapter(ZonedDateTime.class,
(JsonDeserializer<ZonedDateTime>) (json, type, jsonDeserializationContext) -> ZonedDateTime (JsonDeserializer<ZonedDateTime>) (json, type, jsonDeserializationContext) -> ZonedDateTime
.parse(json.getAsJsonPrimitive().getAsString()) .parse(json.getAsJsonPrimitive().getAsString())

View File

@ -17,6 +17,7 @@ import static org.openhab.binding.openuv.internal.OpenUVBindingConstants.*;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -28,6 +29,7 @@ import org.openhab.binding.openuv.internal.config.ReportConfiguration;
import org.openhab.binding.openuv.internal.config.SafeExposureConfiguration; import org.openhab.binding.openuv.internal.config.SafeExposureConfiguration;
import org.openhab.binding.openuv.internal.json.OpenUVResult; import org.openhab.binding.openuv.internal.json.OpenUVResult;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.PointType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
@ -56,6 +58,17 @@ import org.slf4j.LoggerFactory;
*/ */
@NonNullByDefault @NonNullByDefault
public class OpenUVReportHandler extends BaseThingHandler { public class OpenUVReportHandler extends BaseThingHandler {
private static final DecimalType ALERT_GREEN = DecimalType.ZERO;
private static final DecimalType ALERT_YELLOW = new DecimalType(1);
private static final DecimalType ALERT_ORANGE = new DecimalType(2);
private static final DecimalType ALERT_RED = new DecimalType(3);
private static final DecimalType ALERT_PURPLE = new DecimalType(4);
private static final State ALERT_UNDEF = HSBType.fromRGB(179, 179, 179);
private static final Map<State, State> ALERT_COLORS = Map.of(ALERT_GREEN, HSBType.fromRGB(85, 139, 47),
ALERT_YELLOW, HSBType.fromRGB(249, 168, 37), ALERT_ORANGE, HSBType.fromRGB(239, 108, 0), ALERT_RED,
HSBType.fromRGB(183, 28, 28), ALERT_PURPLE, HSBType.fromRGB(106, 27, 154));
private final Logger logger = LoggerFactory.getLogger(OpenUVReportHandler.class); private final Logger logger = LoggerFactory.getLogger(OpenUVReportHandler.class);
private @NonNullByDefault({}) OpenUVBridgeHandler bridgeHandler; private @NonNullByDefault({}) OpenUVBridgeHandler bridgeHandler;
@ -195,13 +208,17 @@ public class OpenUVReportHandler extends BaseThingHandler {
if (channelTypeUID != null) { if (channelTypeUID != null) {
switch (channelTypeUID.getId()) { switch (channelTypeUID.getId()) {
case UV_INDEX: case UV_INDEX:
updateState(channelUID, openUVData.getUv()); updateState(channelUID, asDecimalType(openUVData.getUv()));
break;
case ALERT_LEVEL:
updateState(channelUID, asAlertLevel(openUVData.getUv()));
break; break;
case UV_COLOR: case UV_COLOR:
updateState(channelUID, getAsHSB(openUVData.getUv().intValue())); updateState(channelUID,
ALERT_COLORS.getOrDefault(asAlertLevel(openUVData.getUv()), ALERT_UNDEF));
break; break;
case UV_MAX: case UV_MAX:
updateState(channelUID, openUVData.getUvMax()); updateState(channelUID, asDecimalType(openUVData.getUvMax()));
break; break;
case OZONE: case OZONE:
updateState(channelUID, new QuantityType<>(openUVData.getOzone(), SmartHomeUnits.DOBSON_UNIT)); updateState(channelUID, new QuantityType<>(openUVData.getOzone(), SmartHomeUnits.DOBSON_UNIT));
@ -228,17 +245,25 @@ public class OpenUVReportHandler extends BaseThingHandler {
} }
} }
private State getAsHSB(int uv) { private State asDecimalType(int uv) {
if (uv >= 11) { if (uv >= 1) {
return HSBType.fromRGB(106, 27, 154); return new DecimalType(uv);
} else if (uv >= 8) {
return HSBType.fromRGB(183, 28, 28);
} else if (uv >= 6) {
return HSBType.fromRGB(239, 108, 0);
} else if (uv >= 3) {
return HSBType.fromRGB(249, 168, 37);
} else {
return HSBType.fromRGB(85, 139, 47);
} }
return UnDefType.NULL;
}
private State asAlertLevel(int uv) {
if (uv >= 11) {
return ALERT_PURPLE;
} else if (uv >= 8) {
return ALERT_RED;
} else if (uv >= 6) {
return ALERT_ORANGE;
} else if (uv >= 3) {
return ALERT_YELLOW;
} else if (uv >= 1) {
return ALERT_GREEN;
}
return UnDefType.NULL;
} }
} }

View File

@ -18,7 +18,6 @@ import java.time.ZonedDateTime;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.types.State; import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType; import org.openhab.core.types.UnDefType;
@ -31,23 +30,23 @@ import org.openhab.core.types.UnDefType;
@NonNullByDefault @NonNullByDefault
public class OpenUVResult { public class OpenUVResult {
private final ZonedDateTime DEFAULT_ZDT = ZonedDateTime.of(LocalDateTime.MIN, ZoneId.systemDefault()); private final ZonedDateTime DEFAULT_ZDT = ZonedDateTime.of(LocalDateTime.MIN, ZoneId.systemDefault());
private DecimalType uv = new DecimalType(0); private double uv;
private ZonedDateTime uvTime = DEFAULT_ZDT; private ZonedDateTime uvTime = DEFAULT_ZDT;
private DecimalType uvMax = new DecimalType(0); private double uvMax;
private ZonedDateTime uvMaxTime = DEFAULT_ZDT; private ZonedDateTime uvMaxTime = DEFAULT_ZDT;
private DecimalType ozone = new DecimalType(0); private double ozone;
private ZonedDateTime ozoneTime = DEFAULT_ZDT; private ZonedDateTime ozoneTime = DEFAULT_ZDT;
private SafeExposureTime safeExposureTime = new SafeExposureTime(); private SafeExposureTime safeExposureTime = new SafeExposureTime();
public DecimalType getUv() { public int getUv() {
return uv; return (int) uv;
} }
public DecimalType getUvMax() { public int getUvMax() {
return uvMax; return (int) uvMax;
} }
public DecimalType getOzone() { public double getOzone() {
return ozone; return ozone;
} }

View File

@ -35,6 +35,7 @@
<channels> <channels>
<channel id="UVIndex" typeId="UVIndex"/> <channel id="UVIndex" typeId="UVIndex"/>
<channel id="Alert" typeId="Alert"/>
<channel id="UVColor" typeId="UVColor"/> <channel id="UVColor" typeId="UVColor"/>
<channel id="UVMax" typeId="UVMax"/> <channel id="UVMax" typeId="UVMax"/>
<channel id="UVMaxTime" typeId="UVMaxTime"/> <channel id="UVMaxTime" typeId="UVMaxTime"/>
@ -66,14 +67,14 @@
<item-type>Number</item-type> <item-type>Number</item-type>
<label>UV Index</label> <label>UV Index</label>
<description>UV Index</description> <description>UV Index</description>
<state readOnly="true" pattern="%.2f/16" min="0" max="16"/> <state readOnly="true" pattern="%d/16" min="0" max="16"/>
</channel-type> </channel-type>
<channel-type id="UVMax" advanced="true"> <channel-type id="UVMax" advanced="true">
<item-type>Number</item-type> <item-type>Number</item-type>
<label>UV Max</label> <label>UV Max</label>
<description>Max UV Index for the day (at solar noon)</description> <description>Max UV Index for the day (at solar noon)</description>
<state readOnly="true" pattern="%.2f/16" min="0" max="16"/> <state readOnly="true" pattern="%d/16" min="0" max="16"/>
</channel-type> </channel-type>
<channel-type id="Ozone"> <channel-type id="Ozone">
@ -86,7 +87,8 @@
<channel-type id="OzoneTime" advanced="true"> <channel-type id="OzoneTime" advanced="true">
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>Ozone Observation Time</label> <label>Ozone Observation Time</label>
<description>Latest OMI ozone update time</description> <description>Latest OMI ozone update timestamp.</description>
<category>time</category>
<state readOnly="true" pattern="%1$tF %1$tR"/> <state readOnly="true" pattern="%1$tF %1$tR"/>
</channel-type> </channel-type>
@ -94,20 +96,22 @@
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>UV Max Time</label> <label>UV Max Time</label>
<description>Max UV Index time (solar noon)</description> <description>Max UV Index time (solar noon)</description>
<category>time</category>
<state readOnly="true" pattern="%1$tF %1$tR"/> <state readOnly="true" pattern="%1$tF %1$tR"/>
</channel-type> </channel-type>
<channel-type id="UVTime" advanced="true"> <channel-type id="UVTime" advanced="true">
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>UV Time</label> <label>UV Time</label>
<description>UV Index time</description> <description>UV Index timestamp.</description>
<category>time</category>
<state readOnly="true" pattern="%1$tF %1$tR"/> <state readOnly="true" pattern="%1$tF %1$tR"/>
</channel-type> </channel-type>
<channel-type id="UVColor" advanced="true"> <channel-type id="UVColor" advanced="true">
<item-type>Color</item-type> <item-type>Color</item-type>
<label>UV Color</label> <label>UV Alert Color</label>
<description>Color associated to given UV Index.</description> <description>Color associated to given UV Index alert level.</description>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
@ -147,4 +151,18 @@
<description>Triggers when current UV Index reaches maximum of the day</description> <description>Triggers when current UV Index reaches maximum of the day</description>
</channel-type> </channel-type>
<channel-type id="Alert">
<item-type>Number</item-type>
<label>UV Alert</label>
<state readOnly="true">
<options>
<option value="0">Low</option>
<option value="1">Medium</option>
<option value="2">High</option>
<option value="3">Very high</option>
<option value="4">Extreme</option>
</options>
</state>
</channel-type>
</thing:thing-descriptions> </thing:thing-descriptions>