| 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 |
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/\<station-model\>.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 AmbientWeather<StationModel>Processor
+#### Create Processor Class <StationModel>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
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.
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);
public static final ThingTypeUID UID_WS0265 = new ThingTypeUID(BINDING_ID, THING_TYPE_WS0265);
// Collection of weather station thing types
- public static final Set<ThingTypeUID> 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<ThingTypeUID> 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<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(
// 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";
// 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;
}
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) {
--- /dev/null
+/**
+ * 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);
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="ambientweather"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+ <!-- Ambient Weather WS-2902B -->
+ <thing-type id="ws2902b">
+ <supported-bridge-type-refs>
+ <bridge-type-ref id="bridge"/>
+ </supported-bridge-type-refs>
+
+ <label>WS-2902B</label>
+ <description>Ambient Weather Station WS-2902B</description>
+ <channel-groups>
+ <channel-group id="station" typeId="station">
+ <label>Weather Station</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="weatherDataWs2902b" typeId="weatherDataWs2902b">
+ <label>Weather Data</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="indoorSensor" typeId="indoorSensor">
+ <label>Indoor Sensor</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor1" typeId="remoteSensor">
+ <label>Remote Sensor 1</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor2" typeId="remoteSensor">
+ <label>Remote Sensor 2</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor3" typeId="remoteSensor">
+ <label>Remote Sensor 3</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor4" typeId="remoteSensor">
+ <label>Remote Sensor 4</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor5" typeId="remoteSensor">
+ <label>Remote Sensor 5</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor6" typeId="remoteSensor">
+ <label>Remote Sensor 6</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor7" typeId="remoteSensor">
+ <label>Remote Sensor 7</label>
+ <description></description>
+ </channel-group>
+ <channel-group id="remoteSensor8" typeId="remoteSensor">
+ <label>Remote Sensor 8</label>
+ <description></description>
+ </channel-group>
+ </channel-groups>
+ <config-description-ref uri="thing-type:ambientweather:station"/>
+ </thing-type>
+
+ <!-- Channel group type specific to WS-2902B -->
+ <channel-group-type id="weatherDataWs2902b">
+ <label>Weather Data</label>
+ <description>Weather Data</description>
+ <channels>
+ <channel id="observationTime" typeId="observationTime"/>
+ <channel id="batteryIndicator" typeId="batteryIndicator"/>
+ <channel id="temperature" typeId="temperature"/>
+ <channel id="dewPoint" typeId="dewPoint"/>
+ <channel id="feelingTemperature" typeId="feelingTemperature"/>
+ <channel id="relativeHumidity" typeId="relativeHumidity"/>
+ <channel id="pressureAbsolute" typeId="pressure"/>
+ <channel id="pressureRelative" typeId="pressure"/>
+ <channel id="pressureTrend" typeId="pressureTrend"/>
+ <channel id="windDirectionDegrees" typeId="windDirectionDegrees"/>
+ <channel id="windDirection" typeId="windDirection"/>
+ <channel id="windSpeed" typeId="windSpeed"/>
+ <channel id="windGust" typeId="windGust"/>
+ <channel id="windGustMaxDaily" typeId="windGustMaxDaily"/>
+ <channel id="rainHourlyRate" typeId="rainHourlyRate"/>
+ <channel id="rainDay" typeId="rainDay"/>
+ <channel id="rainWeek" typeId="rainWeek"/>
+ <channel id="rainMonth" typeId="rainMonth"/>
+ <channel id="rainYear" typeId="rainYear"/>
+ <channel id="rainTotal" typeId="rainTotal"/>
+ <channel id="rainEvent" typeId="rainEvent"/>
+ <channel id="rainLastTime" typeId="rainLastTime"/>
+ <channel id="solarRadiation" typeId="solarRadiation"/>
+ <channel id="uvIndex" typeId="uvIndex"/>
+ <channel id="uvDanger" typeId="uvDanger"/>
+ </channels>
+ </channel-group-type>
+
+</thing:thing-descriptions>