diff --git a/bundles/org.openhab.binding.ambientweather/README.md b/bundles/org.openhab.binding.ambientweather/README.md index 047ab907d..557a8f300 100644 --- a/bundles/org.openhab.binding.ambientweather/README.md +++ b/bundles/org.openhab.binding.ambientweather/README.md @@ -12,7 +12,8 @@ The binding currently supports weather data from these weather stations. | Account | bridge | | WS-0900-IP | ws0900ip | | WS-1400-IP / WS-1401-IP | ws1400ip | -| WS-2902A | ws2902a | +| WS-2902A / WS2902C | ws2902a | +| WS-2902B | ws2902b | | WS-8482 | ws8482 | | WS-0265 | ws0265 | @@ -234,16 +235,20 @@ Adding support for a new weather station type involves changes to the source cod Define a new `ThingTypeUID` for the new station and add it to the `SUPPORTED_THING_TYPES_UIDS` Collection. +Add a channel group for the new station. + #### Create OH-INF/thing/\.xml Add thing type and channel group specific to the data elements supported by this weather station. Modeling this after an existing thing type that shares many of the channels is the easiest starting point. You can determine the weather data elements returned for the weather station by putting the binding into debug mode and reviewing the JSON object returned by the Ambient Weather API. -#### Create Processor Class AmbientWeatherProcessor +#### Create Processor Class Processor Add a class in `org.openhab.binding.ambientweather.internal.processor` that defines the channels supported by this station type. + Add the following two methods. + Again, the easiest approach is to model this class after a class for a similar weather station type. ##### Method: processInfoUpdate @@ -254,6 +259,6 @@ Updates the channels for station name and location. Updates channels for weather data. -#### Update AmbientWeatherProcessorFactory.java +#### Update ProcessorFactory.java -Add new Processor class definition to `AmbientWeatherProcessorFactory.java`, and add a new case to the switch statement to return the new processor. +Add new Processor class definition to `ProcessorFactory.java`, and add a new case to the switch statement to return the new processor. diff --git a/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/AmbientWeatherBindingConstants.java b/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/AmbientWeatherBindingConstants.java index d02013039..87d620378 100644 --- a/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/AmbientWeatherBindingConstants.java +++ b/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/AmbientWeatherBindingConstants.java @@ -45,6 +45,10 @@ public class AmbientWeatherBindingConstants { public static final String THING_TYPE_WS2902A = "ws2902a"; public static final ThingTypeUID UID_WS2902A = new ThingTypeUID(BINDING_ID, THING_TYPE_WS2902A); + // WS-2902B series weather stations + public static final String THING_TYPE_WS2902B = "ws2902b"; + public static final ThingTypeUID UID_WS2902B = new ThingTypeUID(BINDING_ID, THING_TYPE_WS2902B); + // WS-8482 weather station public static final String THING_TYPE_WS8482 = "ws8482"; public static final ThingTypeUID UID_WS8482 = new ThingTypeUID(BINDING_ID, THING_TYPE_WS8482); @@ -58,8 +62,9 @@ public class AmbientWeatherBindingConstants { public static final ThingTypeUID UID_WS0265 = new ThingTypeUID(BINDING_ID, THING_TYPE_WS0265); // Collection of weather station thing types - public static final Set SUPPORTED_STATION_THING_TYPES_UIDS = Collections.unmodifiableSet( - Stream.of(UID_WS1400IP, UID_WS2902A, UID_WS8482, UID_WS0900IP, UID_WS0265).collect(Collectors.toSet())); + public static final Set SUPPORTED_STATION_THING_TYPES_UIDS = Collections + .unmodifiableSet(Stream.of(UID_WS1400IP, UID_WS2902A, UID_WS2902B, UID_WS8482, UID_WS0900IP, UID_WS0265) + .collect(Collectors.toSet())); // Collection of all supported thing types public static final Set SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet( @@ -69,6 +74,7 @@ public class AmbientWeatherBindingConstants { // Channel groups for specific weather stations public static final String CHGRP_WS1400IP = "weatherDataWs1400ip"; public static final String CHGRP_WS2902A = "weatherDataWs2902a"; + public static final String CHGRP_WS2902B = "weatherDataWs2902b"; public static final String CHGRP_WS8482 = "weatherDataWs8482"; public static final String CHGRP_WS0900IP = "weatherDataWs0900ip"; public static final String CHGRP_WS0265 = "weatherDataWs0265"; diff --git a/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/processor/ProcessorFactory.java b/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/processor/ProcessorFactory.java index b12ec2a07..84257bcfb 100644 --- a/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/processor/ProcessorFactory.java +++ b/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/processor/ProcessorFactory.java @@ -37,6 +37,7 @@ public class ProcessorFactory { // Supported weather stations private @Nullable static Ws1400ipProcessor WS1400IP_PROCESSOR; private @Nullable static Ws2902aProcessor WS2902A_PROCESSOR; + private @Nullable static Ws2902bProcessor WS2902B_PROCESSOR; private @Nullable static Ws8482Processor WS8482_PROCESSOR; private @Nullable static Ws0900ipProcessor WS0900IP_PROCESSOR; private @Nullable static Ws0265Processor WS0265_PROCESSOR; @@ -78,6 +79,14 @@ public class ProcessorFactory { } return processor; } + case "ambientweather:ws2902b": { + Ws2902bProcessor processor = WS2902B_PROCESSOR; + if (processor == null) { + processor = new Ws2902bProcessor(); + WS2902B_PROCESSOR = processor; + } + return processor; + } case "ambientweather:ws8482": { Ws8482Processor processor = WS8482_PROCESSOR; if (processor == null) { diff --git a/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/processor/Ws2902bProcessor.java b/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/processor/Ws2902bProcessor.java new file mode 100644 index 000000000..26c8c8b0c --- /dev/null +++ b/bundles/org.openhab.binding.ambientweather/src/main/java/org/openhab/binding/ambientweather/internal/processor/Ws2902bProcessor.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2010-2020 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.ambientweather.internal.processor; + +import static org.openhab.binding.ambientweather.internal.AmbientWeatherBindingConstants.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.ambientweather.internal.handler.AmbientWeatherStationHandler; +import org.openhab.binding.ambientweather.internal.model.EventDataJson; +import org.openhab.core.library.unit.ImperialUnits; +import org.openhab.core.library.unit.SmartHomeUnits; + +/** + * The {@link Ws2902bProcessor} is responsible for updating + * the channels associated with the WS-2902A weather stations in + * response to the receipt of a weather data update from the Ambient + * Weather real-time API. + * + * @author Mark Hilbush - Initial contribution + */ +@NonNullByDefault +public class Ws2902bProcessor extends AbstractProcessor { + + @Override + public void setChannelGroupId() { + channelGroupId = CHGRP_WS2902B; + } + + @Override + public void setNumberOfSensors() { + remoteSensor.setNumberOfSensors(8); + } + + @Override + public void processInfoUpdate(AmbientWeatherStationHandler handler, String station, String name, String location) { + // Update name and location channels + handler.updateString(CHGRP_STATION, CH_NAME, name); + handler.updateString(CHGRP_STATION, CH_LOCATION, location); + } + + @Override + public void processWeatherData(AmbientWeatherStationHandler handler, String station, String jsonData) { + EventDataJson data = parseEventData(station, jsonData); + if (data == null) { + return; + } + + // Update the weather data channels + handler.updateDate(channelGroupId, CH_OBSERVATION_TIME, data.date); + handler.updateString(channelGroupId, CH_BATTERY_INDICATOR, NOT_APPLICABLE); + handler.updateQuantity(channelGroupId, CH_TEMPERATURE, data.tempf, ImperialUnits.FAHRENHEIT); + handler.updateQuantity(channelGroupId, CH_FEELING_TEMPERATURE, data.feelsLike, ImperialUnits.FAHRENHEIT); + handler.updateQuantity(channelGroupId, CH_DEW_POINT, data.dewPoint, ImperialUnits.FAHRENHEIT); + handler.updateQuantity(channelGroupId, CH_HUMIDITY, data.humidity, SmartHomeUnits.PERCENT); + handler.updateQuantity(channelGroupId, CH_PRESSURE_ABSOLUTE, data.baromabsin, ImperialUnits.INCH_OF_MERCURY); + handler.updateQuantity(channelGroupId, CH_PRESSURE_RELATIVE, data.baromrelin, ImperialUnits.INCH_OF_MERCURY); + handler.updateQuantity(channelGroupId, CH_WIND_SPEED, data.windspeedmph, ImperialUnits.MILES_PER_HOUR); + handler.updateQuantity(channelGroupId, CH_WIND_DIRECTION_DEGREES, data.winddir, SmartHomeUnits.DEGREE_ANGLE); + handler.updateQuantity(channelGroupId, CH_WIND_GUST, data.windgustmph, ImperialUnits.MILES_PER_HOUR); + handler.updateQuantity(channelGroupId, CH_WIND_GUST_MAX_DAILY, data.maxdailygust, ImperialUnits.MILES_PER_HOUR); + handler.updateQuantity(channelGroupId, CH_SOLAR_RADIATION, data.solarradiation, SmartHomeUnits.IRRADIANCE); + handler.updateNumber(channelGroupId, CH_UV_INDEX, data.uv); + handler.updateQuantity(channelGroupId, CH_RAIN_HOURLY_RATE, data.hourlyrainin, SmartHomeUnits.INCHES_PER_HOUR); + handler.updateQuantity(channelGroupId, CH_RAIN_DAY, data.dailyrainin, ImperialUnits.INCH); + handler.updateQuantity(channelGroupId, CH_RAIN_WEEK, data.weeklyrainin, ImperialUnits.INCH); + handler.updateQuantity(channelGroupId, CH_RAIN_MONTH, data.monthlyrainin, ImperialUnits.INCH); + handler.updateQuantity(channelGroupId, CH_RAIN_YEAR, data.yearlyrainin, ImperialUnits.INCH); + handler.updateQuantity(channelGroupId, CH_RAIN_TOTAL, data.totalrainin, ImperialUnits.INCH); + handler.updateQuantity(channelGroupId, CH_RAIN_EVENT, data.eventrainin, ImperialUnits.INCH); + handler.updateDate(channelGroupId, CH_RAIN_LAST_TIME, data.lastRain); + + // Update calculated channels + if (data.baromrelin != null) { + pressureTrend.put(data.baromrelin); + handler.updateString(channelGroupId, CH_PRESSURE_TREND, pressureTrend.getPressureTrend()); + } + if (data.winddir != null) { + handler.updateString(channelGroupId, CH_WIND_DIRECTION, convertWindDirectionToString(data.winddir)); + } + if (data.uv != null) { + handler.updateString(channelGroupId, CH_UV_DANGER, convertUVIndexToString(data.uv)); + } + + // Update indoor sensor channels + handler.updateQuantity(CHGRP_INDOOR_SENSOR, CH_TEMPERATURE, data.tempinf, ImperialUnits.FAHRENHEIT); + handler.updateQuantity(CHGRP_INDOOR_SENSOR, CH_HUMIDITY, data.humidityin, SmartHomeUnits.PERCENT); + handler.updateString(CHGRP_INDOOR_SENSOR, CH_BATTERY_INDICATOR, NOT_APPLICABLE); + + // Update channels for the remote sensors + remoteSensor.updateChannels(handler, jsonData); + } +} diff --git a/bundles/org.openhab.binding.ambientweather/src/main/resources/OH-INF/thing/ws2902b.xml b/bundles/org.openhab.binding.ambientweather/src/main/resources/OH-INF/thing/ws2902b.xml new file mode 100644 index 000000000..06b959545 --- /dev/null +++ b/bundles/org.openhab.binding.ambientweather/src/main/resources/OH-INF/thing/ws2902b.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + Ambient Weather Station WS-2902B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Weather Data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +