Set channel states to UNDEF instead of NULL; Fixed SAT warnings (#10421)

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
Christoph Weitkamp 2021-03-31 21:42:33 +02:00 committed by GitHub
parent aa97da083c
commit 12b0908806
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 70 additions and 63 deletions

View File

@ -132,7 +132,9 @@ then
end end
``` ```
dwdunwetter_de.map dwdunwetter_de.map
``` ```
ON=aktiv ON=aktiv
OFF=inaktiv OFF=inaktiv
@ -151,8 +153,6 @@ NULL=undefiniert
UNDEF=undefiniert UNDEF=undefiniert
``` ```
dwdunwetter_urgency_de.map dwdunwetter_urgency_de.map
``` ```

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Instant; import java.time.Instant;

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.io.StringReader; import java.io.StringReader;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -218,18 +218,18 @@ public class DwdWarningsData {
public State getSeverity(int number) { public State getSeverity(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
return data == null ? UnDefType.NULL : StringType.valueOf(data.getSeverity().getText()); return data == null ? UnDefType.UNDEF : StringType.valueOf(data.getSeverity().getText());
} }
public State getDescription(int number) { public State getDescription(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
return data == null ? UnDefType.NULL : StringType.valueOf(data.getDescription()); return data == null ? UnDefType.UNDEF : StringType.valueOf(data.getDescription());
} }
public State getEffective(int number) { public State getEffective(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
if (data == null) { if (data == null) {
return UnDefType.NULL; return UnDefType.UNDEF;
} }
ZonedDateTime zoned = ZonedDateTime.ofInstant(data.getEffective(), ZoneId.systemDefault()); ZonedDateTime zoned = ZonedDateTime.ofInstant(data.getEffective(), ZoneId.systemDefault());
return new DateTimeType(zoned); return new DateTimeType(zoned);
@ -238,7 +238,7 @@ public class DwdWarningsData {
public State getExpires(int number) { public State getExpires(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
if (data == null) { if (data == null) {
return UnDefType.NULL; return UnDefType.UNDEF;
} }
ZonedDateTime zoned = ZonedDateTime.ofInstant(data.getExpires(), ZoneId.systemDefault()); ZonedDateTime zoned = ZonedDateTime.ofInstant(data.getExpires(), ZoneId.systemDefault());
return new DateTimeType(zoned); return new DateTimeType(zoned);
@ -247,7 +247,7 @@ public class DwdWarningsData {
public State getOnset(int number) { public State getOnset(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
if (data == null) { if (data == null) {
return UnDefType.NULL; return UnDefType.UNDEF;
} }
ZonedDateTime zoned = ZonedDateTime.ofInstant(data.getOnset(), ZoneId.systemDefault()); ZonedDateTime zoned = ZonedDateTime.ofInstant(data.getOnset(), ZoneId.systemDefault());
return new DateTimeType(zoned); return new DateTimeType(zoned);
@ -255,18 +255,18 @@ public class DwdWarningsData {
public State getEvent(int number) { public State getEvent(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
return data == null ? UnDefType.NULL : StringType.valueOf(data.getEvent()); return data == null ? UnDefType.UNDEF : StringType.valueOf(data.getEvent());
} }
public State getHeadline(int number) { public State getHeadline(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
return data == null ? UnDefType.NULL : StringType.valueOf(data.getHeadline()); return data == null ? UnDefType.UNDEF : StringType.valueOf(data.getHeadline());
} }
public State getAltitude(int number) { public State getAltitude(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
if (data == null) { if (data == null) {
return UnDefType.NULL; return UnDefType.UNDEF;
} }
return new QuantityType<>(data.getAltitude(), ImperialUnits.FOOT); return new QuantityType<>(data.getAltitude(), ImperialUnits.FOOT);
} }
@ -274,19 +274,19 @@ public class DwdWarningsData {
public State getCeiling(int number) { public State getCeiling(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
if (data == null) { if (data == null) {
return UnDefType.NULL; return UnDefType.UNDEF;
} }
return new QuantityType<>(data.getCeiling(), ImperialUnits.FOOT); return new QuantityType<>(data.getCeiling(), ImperialUnits.FOOT);
} }
public State getInstruction(int number) { public State getInstruction(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
return data == null ? UnDefType.NULL : StringType.valueOf(data.getInstruction()); return data == null ? UnDefType.UNDEF : StringType.valueOf(data.getInstruction());
} }
public State getUrgency(int number) { public State getUrgency(int number) {
DwdWarningData data = getGemeindeData(number); DwdWarningData data = getGemeindeData(number);
return data == null ? UnDefType.NULL : StringType.valueOf(data.getUrgency().getText()); return data == null ? UnDefType.UNDEF : StringType.valueOf(data.getUrgency().getText());
} }
public boolean isNew(int number) { public boolean isNew(int number) {

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.util.Arrays; import java.util.Arrays;

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.util.Arrays; import java.util.Arrays;

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.util.Comparator; import java.util.Comparator;

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import java.util.Arrays; import java.util.Arrays;

View File

@ -23,7 +23,7 @@ import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.dwdunwetter.internal.config.DwdUnwetterConfiguration; import org.openhab.binding.dwdunwetter.internal.config.DwdUnwetterConfiguration;
import org.openhab.binding.dwdunwetter.internal.data.DwdWarningsData; import org.openhab.binding.dwdunwetter.internal.dto.DwdWarningsData;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.Channel; import org.openhab.core.thing.Channel;

View File

@ -1,10 +1,10 @@
# binding # binding
binding.dwdunwetter.name = DWD Unwetter Binding binding.dwdunwetter.name = DWD Unwetter Binding
binding.dwdunwetter.description = Das DWD Unwetter Binding ermöglicht es über die API des DWD aktuelle Unwetterwarnungen abzurufen binding.dwdunwetter.description = Das DWD Unwetter Binding ermöglicht es über die API des DWD aktuelle Unwetterwarnungen abzurufen.
# thing types # thing types
thing-type.dwdunwetter.dwdwarnings.label = DWD Unwetter Warnungen thing-type.dwdunwetter.dwdwarnings.label = DWD Unwetter Warnungen
thing-type.dwdunwetter.dwdwarnings.description = DWD Unwetterwarnungen für ein Gebiet thing-type.dwdunwetter.dwdwarnings.description = DWD Unwetterwarnungen für ein Gebiet.
thing-type.config.dwdunwetter.dwdwarnings.cellId.label=Cell-ID thing-type.config.dwdunwetter.dwdwarnings.cellId.label=Cell-ID
thing-type.config.dwdunwetter.dwdwarnings.cellId.description=ID der abzufragenden Zelle.\ thing-type.config.dwdunwetter.dwdwarnings.cellId.description=ID der abzufragenden Zelle.\
@ -20,29 +20,29 @@ Die Warnungen werden dabei nach Severity und dann nach Beginn sortiert. Die erst
channel-type.dwdunwetter.warning.label = Warnung channel-type.dwdunwetter.warning.label = Warnung
channel-type.dwdunwetter.warning.description = Steht auf ON, wenn eine Warning vorliegt, OFF wenn keine vorliegt.\ channel-type.dwdunwetter.warning.description = Steht auf ON, wenn eine Warning vorliegt, OFF wenn keine vorliegt.\
Es ist garantiert, dass wenn der Channel von OFF auf ON umspringt, die anderen Channels bereits gefüllt sind, mit Ausnahme des Trigger Channels.\ Es ist garantiert, dass wenn der Channel von OFF auf ON umspringt, die anderen Channels bereits gefüllt sind, mit Ausnahme des Trigger Channels.\
Es ist garantiert, dass wenn der Channel von ON auf OFF umspringt, die anderen Channels erst danach auf NULL gesetzt werden. Es ist garantiert, dass wenn der Channel von ON auf OFF umspringt, die anderen Channels erst danach auf UNDEF gesetzt werden.
channel-type.dwdunwetter.updated.label = Aktualisiert channel-type.dwdunwetter.updated.label = Aktualisiert
channel-type.dwdunwetter.updated.description = Triggered, wenn eine Warnung das erste mal gesendet wird.\ channel-type.dwdunwetter.updated.description = Triggered, wenn eine Warnung das erste mal gesendet wird.\
Dies passiert als letztes, nachdem alle anderen Channels bereits gesetzt sind. Dies passiert als letztes, nachdem alle anderen Channels bereits gesetzt sind.
channel-type.dwdunwetter.severity.label = Schwere-Grad channel-type.dwdunwetter.severity.label = Schwere-Grad
channel-type.dwdunwetter.severity.description = Schwere-Grad der Warnung. Mögliche Werte sind Minor, Moderate, Severe und Extreme. channel-type.dwdunwetter.severity.description = Schwere-Grad der Warnung. Mögliche Werte sind Minor, Moderate, Severe und Extreme.
channel-type.dwdunwetter.description.label = Beschreibung channel-type.dwdunwetter.description.label = Beschreibung
channel-type.dwdunwetter.description.description = Klartext Beschreibung der Warnung channel-type.dwdunwetter.description.description = Klartext Beschreibung der Warnung.
channel-type.dwdunwetter.effective.label = Ausgegeben channel-type.dwdunwetter.effective.label = Ausgegeben
channel-type.dwdunwetter.effective.description = Datum und Uhrzeit, wann die Warnung ausgegeben wurde channel-type.dwdunwetter.effective.description = Datum und Uhrzeit, wann die Warnung ausgegeben wurde.
channel-type.dwdunwetter.onset.label = Gültig ab channel-type.dwdunwetter.onset.label = Gültig ab
channel-type.dwdunwetter.onset.description = Datum und Uhrzeit, ab dem die Warnung gültig ist channel-type.dwdunwetter.onset.description = Datum und Uhrzeit, ab dem die Warnung gültig ist.
channel-type.dwdunwetter.expires.label = Gültig bis channel-type.dwdunwetter.expires.label = Gültig bis
channel-type.dwdunwetter.expires.description = Datum und Uhrzeit, bis zu dem die Warnung gültig ist channel-type.dwdunwetter.expires.description = Datum und Uhrzeit, bis zu dem die Warnung gültig ist.
channel-type.dwdunwetter.headline.label = Titel channel-type.dwdunwetter.headline.label = Titel
channel-type.dwdunwetter.headline.description = Titel der Warnung z.B. "Amtliche Warnung vor FROST" channel-type.dwdunwetter.headline.description = Titel der Warnung z.B. "Amtliche Warnung vor FROST".
channel-type.dwdunwetter.event.label = Art channel-type.dwdunwetter.event.label = Art
channel-type.dwdunwetter.event.description = Art der Warnung, z.B. FROST channel-type.dwdunwetter.event.description = Art der Warnung, z.B. FROST.
channel-type.dwdunwetter.altitude.label = Höhe von channel-type.dwdunwetter.altitude.label = Höhe von
channel-type.dwdunwetter.altitude.description = Höhe über dem Meeresspiegel, ab dem die Warnung gilt channel-type.dwdunwetter.altitude.description = Höhe über dem Meeresspiegel, ab dem die Warnung gilt.
channel-type.dwdunwetter.ceiling.label = Höhe bis channel-type.dwdunwetter.ceiling.label = Höhe bis
channel-type.dwdunwetter.ceiling.description = Höhe über dem Meeresspiegel, bis zu dem die Warnung gilt channel-type.dwdunwetter.ceiling.description = Höhe über dem Meeresspiegel, bis zu dem die Warnung gilt.
channel-type.dwdunwetter.urgency.label=Zeitrahmen channel-type.dwdunwetter.urgency.label=Zeitrahmen
channel-type.dwdunwetter.urgency.description=Zeitrahmen der Meldung - Vorabinformation oder Warnung channel-type.dwdunwetter.urgency.description=Zeitrahmen der Meldung - Vorabinformation oder Warnung.
channel-type.dwdunwetter.instruction.label=Zusatztext channel-type.dwdunwetter.instruction.label=Zusatztext
channel-type.dwdunwetter.instruction.description=Zusatztext zur Warnung (Instruktionen und Sicherheitshinweise) channel-type.dwdunwetter.instruction.description=Zusatztext zur Warnung (Instruktionen und Sicherheitshinweise).

View File

@ -6,9 +6,9 @@
<thing-type id="dwdwarnings"> <thing-type id="dwdwarnings">
<label>Weather Warnings</label> <label>Weather Warnings</label>
<description>Weather Warnings for an area</description> <description>Weather Warnings for an area.</description>
<channels> <channels>
<channel typeId="lastUpdated" id="lastUpdated"></channel> <channel typeId="lastUpdated" id="lastUpdated"/>
</channels> </channels>
<config-description> <config-description>
<parameter name="cellId" type="text" required="true"> <parameter name="cellId" type="text" required="true">
@ -35,7 +35,8 @@ The warnings are sorted by severity first and begin second so the first warning
<channel-type id="lastUpdated"> <channel-type id="lastUpdated">
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>Last Updated</label> <label>Last Updated</label>
<description>Timestamp of the last update from the endpoint</description> <description>Timestamp of the last update from the endpoint.</description>
<category>Time</category>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="warning"> <channel-type id="warning">
@ -43,14 +44,14 @@ The warnings are sorted by severity first and begin second so the first warning
<label>Warning</label> <label>Warning</label>
<description><![CDATA[ON if a warning is present, OFF else. <description><![CDATA[ON if a warning is present, OFF else.
While be switched to ON only after all other channels - except the trigger channel - are updated. While be switched to ON only after all other channels - except the trigger channel - are updated.
Will be switched to OFF before all other channels are updated to NULL]]></description> Will be switched to OFF before all other channels are updated to UNDEF.]]></description>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="updated"> <channel-type id="updated">
<kind>trigger</kind> <kind>trigger</kind>
<label>Updated</label> <label>Updated</label>
<description><![CDATA[Triggers NEW if a warning is send the first time. <description><![CDATA[Triggers NEW if a warning is send the first time.
This happens after all other channels are populated]]></description> This happens after all other channels are populated.]]></description>
<event> <event>
<options> <options>
<option value="NEW">New</option> <option value="NEW">New</option>
@ -79,49 +80,52 @@ This happens after all other channels are populated]]></description>
<channel-type id="effective"> <channel-type id="effective">
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>Issued</label> <label>Issued</label>
<description>Issued Date and Time</description> <description>Issued Date and Time.</description>
<category>Time</category>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="onset"> <channel-type id="onset">
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>Valid From</label> <label>Valid From</label>
<description>Start Date and Time for which the warning is valid</description> <description>Start Date and Time for which the warning is valid.</description>
<category>Time</category>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="expires"> <channel-type id="expires">
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>Valid To</label> <label>Valid To</label>
<description>End Date and Time for which the warning is valid</description> <description>End Date and Time for which the warning is valid.</description>
<category>Time</category>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="headline"> <channel-type id="headline">
<item-type>String</item-type> <item-type>String</item-type>
<label>Headline</label> <label>Headline</label>
<description>Headline of the warning like "Amtliche Warnung vor FROST"</description> <description>Headline of the warning like "Amtliche Warnung vor FROST".</description>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="event"> <channel-type id="event">
<item-type>String</item-type> <item-type>String</item-type>
<label>Type</label> <label>Type</label>
<description>Type of the warning, e.g. FROST</description> <description>Type of the warning, e.g. FROST.</description>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="altitude"> <channel-type id="altitude">
<item-type>Number:Length</item-type> <item-type>Number:Length</item-type>
<label>Height (from)</label> <label>Height (from)</label>
<description>Lower Height above sea level for which the warning is valid</description> <description>Lower Height above sea level for which the warning is valid.</description>
<state readOnly="true" pattern="%d m"/> <state readOnly="true" pattern="%d m"/>
</channel-type> </channel-type>
<channel-type id="ceiling"> <channel-type id="ceiling">
<item-type>Number:Length</item-type> <item-type>Number:Length</item-type>
<label>Height (to)</label> <label>Height (to)</label>
<description>Upper Height above sea level for which the warning is valid</description> <description>Upper Height above sea level for which the warning is valid.</description>
<state readOnly="true" pattern="%d m"/> <state readOnly="true" pattern="%d m"/>
</channel-type> </channel-type>
<channel-type id="instruction"> <channel-type id="instruction">
<item-type>String</item-type> <item-type>String</item-type>
<label>Instruction</label> <label>Instruction</label>
<description>Instructions and safety information</description> <description>Instructions and safety information.</description>
<state readOnly="true"/> <state readOnly="true"/>
</channel-type> </channel-type>
<channel-type id="urgency"> <channel-type id="urgency">

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
@ -21,7 +21,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
* Tests for {@link DwdWarningCache} * Tests for {@link org.openhab.binding.dwdunwetter.internal.dto.DwdWarningCache}
* *
* @author Martin Koehler - Initial contribution * @author Martin Koehler - Initial contribution
*/ */

View File

@ -10,7 +10,7 @@
* *
* SPDX-License-Identifier: EPL-2.0 * SPDX-License-Identifier: EPL-2.0
*/ */
package org.openhab.binding.dwdunwetter.internal.data; package org.openhab.binding.dwdunwetter.internal.dto;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
@ -30,14 +30,17 @@ import org.openhab.core.library.types.OnOffType;
import org.openhab.core.types.UnDefType; import org.openhab.core.types.UnDefType;
/** /**
* Tests for {@link DwdWarningsData} * Tests for {@link org.openhab.binding.dwdunwetter.internal.dto.DwdWarningsData}
* *
* <p>
* Uses the warnings.xml from the resources directory instead of accessing the api endpoint. * Uses the warnings.xml from the resources directory instead of accessing the api endpoint.
* *
* <p>
* The XML has 2 Entries: * The XML has 2 Entries:
*
* <ol> * <ol>
* <li>Amtliche WARNUNG vor WINDBÖEN, MINOR</li> * <li>Amtliche WARNUNG vor WINDBÖEN, MINOR
* <li>Amtliche WARNUNG vor STURMBÖEN, MODERATE</li> * <li>Amtliche WARNUNG vor STURMBÖEN, MODERATE
* </ol> * </ol>
* *
* @author Martin Koehler - Initial contribution * @author Martin Koehler - Initial contribution
@ -60,21 +63,21 @@ public class DwdWarningsDataTest {
public void testGetHeadline() { public void testGetHeadline() {
assertThat(warningsData.getHeadline(0), is("Amtliche WARNUNG vor STURMBÖEN")); assertThat(warningsData.getHeadline(0), is("Amtliche WARNUNG vor STURMBÖEN"));
assertThat(warningsData.getHeadline(1), is("Amtliche WARNUNG vor WINDBÖEN")); assertThat(warningsData.getHeadline(1), is("Amtliche WARNUNG vor WINDBÖEN"));
assertThat(warningsData.getHeadline(2), is(UnDefType.NULL)); assertThat(warningsData.getHeadline(2), is(UnDefType.UNDEF));
} }
@Test @Test
public void testGetSeverity() { public void testGetSeverity() {
assertThat(warningsData.getSeverity(0), is("Moderate")); assertThat(warningsData.getSeverity(0), is("Moderate"));
assertThat(warningsData.getSeverity(1), is("Minor")); assertThat(warningsData.getSeverity(1), is("Minor"));
assertThat(warningsData.getSeverity(2), is(UnDefType.NULL)); assertThat(warningsData.getSeverity(2), is(UnDefType.UNDEF));
} }
@Test @Test
public void testGetEvent() { public void testGetEvent() {
assertThat(warningsData.getEvent(0), is("STURMBÖEN")); assertThat(warningsData.getEvent(0), is("STURMBÖEN"));
assertThat(warningsData.getEvent(1), is("WINDBÖEN")); assertThat(warningsData.getEvent(1), is("WINDBÖEN"));
assertThat(warningsData.getEvent(2), is(UnDefType.NULL)); assertThat(warningsData.getEvent(2), is(UnDefType.UNDEF));
} }
@Test @Test
@ -83,21 +86,21 @@ public class DwdWarningsDataTest {
"Es treten Sturmböen mit Geschwindigkeiten zwischen 60 km/h (17m/s, 33kn, Bft 7) und 80 km/h (22m/s, 44kn, Bft 9) anfangs aus südwestlicher, später aus westlicher Richtung auf. In Schauernähe sowie in exponierten Lagen muss mit schweren Sturmböen um 90 km/h (25m/s, 48kn, Bft 10) gerechnet werden.")); "Es treten Sturmböen mit Geschwindigkeiten zwischen 60 km/h (17m/s, 33kn, Bft 7) und 80 km/h (22m/s, 44kn, Bft 9) anfangs aus südwestlicher, später aus westlicher Richtung auf. In Schauernähe sowie in exponierten Lagen muss mit schweren Sturmböen um 90 km/h (25m/s, 48kn, Bft 10) gerechnet werden."));
assertThat(warningsData.getDescription(1), is( assertThat(warningsData.getDescription(1), is(
"Es treten Windböen mit Geschwindigkeiten bis 60 km/h (17m/s, 33kn, Bft 7) aus westlicher Richtung auf. In Schauernähe sowie in exponierten Lagen muss mit Sturmböen bis 80 km/h (22m/s, 44kn, Bft 9) gerechnet werden.")); "Es treten Windböen mit Geschwindigkeiten bis 60 km/h (17m/s, 33kn, Bft 7) aus westlicher Richtung auf. In Schauernähe sowie in exponierten Lagen muss mit Sturmböen bis 80 km/h (22m/s, 44kn, Bft 9) gerechnet werden."));
assertThat(warningsData.getDescription(2), is(UnDefType.NULL)); assertThat(warningsData.getDescription(2), is(UnDefType.UNDEF));
} }
@Test @Test
public void testGetAltitude() { public void testGetAltitude() {
assertThat(warningsData.getAltitude(0).format("%.0f ft"), is("0 ft")); assertThat(warningsData.getAltitude(0).format("%.0f ft"), is("0 ft"));
assertThat(warningsData.getAltitude(1).format("%.0f ft"), is("0 ft")); assertThat(warningsData.getAltitude(1).format("%.0f ft"), is("0 ft"));
assertThat(warningsData.getAltitude(2), is(UnDefType.NULL)); assertThat(warningsData.getAltitude(2), is(UnDefType.UNDEF));
} }
@Test @Test
public void testGetCeiling() { public void testGetCeiling() {
assertThat(warningsData.getCeiling(0).format("%.0f ft"), is("9843 ft")); assertThat(warningsData.getCeiling(0).format("%.0f ft"), is("9843 ft"));
assertThat(warningsData.getCeiling(1).format("%.0f ft"), is("9843 ft")); assertThat(warningsData.getCeiling(1).format("%.0f ft"), is("9843 ft"));
assertThat(warningsData.getCeiling(2), is(UnDefType.NULL)); assertThat(warningsData.getCeiling(2), is(UnDefType.UNDEF));
} }
@Test @Test
@ -107,7 +110,7 @@ public class DwdWarningsDataTest {
.toString(), is("2018-12-22T18:00Z[UTC]")); .toString(), is("2018-12-22T18:00Z[UTC]"));
assertThat(((DateTimeType) warningsData.getExpires(1)).getZonedDateTime().withZoneSameInstant(ZoneId.of("UTC")) assertThat(((DateTimeType) warningsData.getExpires(1)).getZonedDateTime().withZoneSameInstant(ZoneId.of("UTC"))
.toString(), is("2018-12-23T01:00Z[UTC]")); .toString(), is("2018-12-23T01:00Z[UTC]"));
assertThat(warningsData.getExpires(2), is(UnDefType.NULL)); assertThat(warningsData.getExpires(2), is(UnDefType.UNDEF));
} }
@Test @Test
@ -117,7 +120,7 @@ public class DwdWarningsDataTest {
.toString(), is("2018-12-21T10:00Z[UTC]")); .toString(), is("2018-12-21T10:00Z[UTC]"));
assertThat(((DateTimeType) warningsData.getOnset(1)).getZonedDateTime().withZoneSameInstant(ZoneId.of("UTC")) assertThat(((DateTimeType) warningsData.getOnset(1)).getZonedDateTime().withZoneSameInstant(ZoneId.of("UTC"))
.toString(), is("2018-12-22T18:00Z[UTC]")); .toString(), is("2018-12-22T18:00Z[UTC]"));
assertThat(warningsData.getOnset(2), is(UnDefType.NULL)); assertThat(warningsData.getOnset(2), is(UnDefType.UNDEF));
} }
@Test @Test
@ -127,7 +130,7 @@ public class DwdWarningsDataTest {
.withZoneSameInstant(ZoneId.of("UTC")).toString(), is("2018-12-22T03:02Z[UTC]")); .withZoneSameInstant(ZoneId.of("UTC")).toString(), is("2018-12-22T03:02Z[UTC]"));
assertThat(((DateTimeType) warningsData.getEffective(1)).getZonedDateTime() assertThat(((DateTimeType) warningsData.getEffective(1)).getZonedDateTime()
.withZoneSameInstant(ZoneId.of("UTC")).toString(), is("2018-12-22T10:15Z[UTC]")); .withZoneSameInstant(ZoneId.of("UTC")).toString(), is("2018-12-22T10:15Z[UTC]"));
assertThat(warningsData.getEffective(2), is(UnDefType.NULL)); assertThat(warningsData.getEffective(2), is(UnDefType.UNDEF));
} }
@Test @Test