[Meteostick] Add windvane calibration (#16270)

* [Meteostick] Add windvane calibration
* [Meteostick] Added daily rain accumulation

Signed-off-by: Cor Hoogendoorn <chiuaua@hotmail.com>
This commit is contained in:
Chiuaua79 2024-02-10 17:03:31 +01:00 committed by GitHub
parent d1caa31d6a
commit d72c5b565b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 105 additions and 39 deletions

View File

@ -41,10 +41,11 @@ Set mode to one of the following depending on your device and region:
### meteostick_davis_iss Configuration Options ### meteostick_davis_iss Configuration Options
| Option | Description | | Option | Description |
|---------|-------------------------------------------| |--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| channel | Sets the RF channel used for this sensor | | channel | Sets the RF channel used for this sensor |
| spoon | Size of rain spoon assembly for this sensor in mm. Default value is 0.254 (0.01") for use with Davis part number 7345.280. Set to 0.2 for use with Davis part number 7345.319 | | spoon | Size of rain spoon assembly for this sensor in mm. Default value is 0.254 (0.01") for use with Davis part number 7345.280. Set to 0.2 for use with Davis part number 7345.319 |
| deltaWindDirection | For Davis 6410, 7911 & 7914 anemometers, if your anemometer cannot be mounted aiming true North set the direction it is aiming here (0 to 359 degrees). Default is 0 (for North) |
## Channels ## Channels
@ -69,15 +70,17 @@ Set mode to one of the following depending on your device and region:
| rain-raw | Number | Raw rain counter from the tipping spoon sensor | | rain-raw | Number | Raw rain counter from the tipping spoon sensor |
| rain-currenthour | Number:Length | The rainfall in the last 60 minutes | | rain-currenthour | Number:Length | The rainfall in the last 60 minutes |
| rain-lasthour | Number:Length | The rainfall in the previous hour | | rain-lasthour | Number:Length | The rainfall in the previous hour |
| rain-today | Number:Length | Accumulated rainfall for today
| solar-power | Number | Solar power from the sensor station | | solar-power | Number | Solar power from the sensor station |
| signal-strength | Number | Received signal strength | | signal-strength | Number | Received signal strength |
| low-battery | Switch | Low battery warning | | low-battery | Switch | Low battery warning |
#### Rainfall #### Rainfall
There are three channels associated with rainfall. There are four channels associated with rainfall.
The raw counter from the tipping bucket is provided, the rainfall in the last 60 minutes is updated on each received rainfall and provides the past 60 minutes of rainfall. The raw counter from the tipping bucket is provided, the rainfall in the last 60 minutes is updated on each received rainfall and provides the past 60 minutes of rainfall.
The rainfall in the previous hour is the rainfall for each hour of the day and is updated on the hour. The rainfall in the previous hour is the rainfall for each hour of the day and is updated on the hour.
The accumulated rainfall for today provides the amount of rain for the current date and will reset to 0 at timezone's midnight.
## Full Example ## Full Example
@ -95,10 +98,10 @@ Things can be defined in the .things file as follows:
```java ```java
meteostick:meteostick_bridge:receiver [ port="/dev/tty.usbserial-AI02XA60", mode=1 ] meteostick:meteostick_bridge:receiver [ port="/dev/tty.usbserial-AI02XA60", mode=1 ]
meteostick:meteostick_davis_iss:iss (meteostick:meteostick_bridge:receiver) [ channel=1, spoon=0.2 ] meteostick:meteostick_davis_iss:iss (meteostick:meteostick_bridge:receiver) [ channel=1, spoon=0.2, deltaWindDirection=0 ]
``` ```
Note the configuration options for `port`, `mode`, `channel` and `spoon` above and adjust as needed for your specific hardware. Note the configuration options for `port`, `mode`, `channel`, `deltaWindDirection` and `spoon` above and adjust as needed for your specific hardware.
### items/meteostick.items ### items/meteostick.items
@ -112,6 +115,7 @@ Number:Speed DavisVantageVueWindSpeed "ISS Wind Speed [%.1f m/s]" { channel="met
Number:Speed DavisVantageVueWindSpeedAverage "ISS Average Wind Speed [%.1f m/s]" { channel="meteostick:meteostick_davis_iss:iss:wind-speed-last2min-average" } Number:Speed DavisVantageVueWindSpeedAverage "ISS Average Wind Speed [%.1f m/s]" { channel="meteostick:meteostick_davis_iss:iss:wind-speed-last2min-average" }
Number:Speed DavisVantageVueWindSpeedMaximum "ISS Maximum Wind Speed [%.1f m/s]" { channel="meteostick:meteostick_davis_iss:iss:wind-speed-last2min-maximum" } Number:Speed DavisVantageVueWindSpeedMaximum "ISS Maximum Wind Speed [%.1f m/s]" { channel="meteostick:meteostick_davis_iss:iss:wind-speed-last2min-maximum" }
Number:Length DavisVantageVueRainCurrentHour "ISS Rain Current Hour [%.1f mm]" { channel="meteostick:meteostick_davis_iss:iss:rain-currenthour" } Number:Length DavisVantageVueRainCurrentHour "ISS Rain Current Hour [%.1f mm]" { channel="meteostick:meteostick_davis_iss:iss:rain-currenthour" }
Number:Length DavisVantageVueRainToday "ISS Rain Today [%.1f mm]" { channel="meteostick:meteostick_davis_iss:iss:rain-today" }
``` ```
### rules/meteostick.rules ### rules/meteostick.rules
@ -157,6 +161,7 @@ then
'dewptf' -> dewptf, 'dewptf' -> dewptf,
'tempf' -> DavisVantageVueOutdoorTemperature.getStateAs(QuantityType).toUnit('°F').doubleValue, 'tempf' -> DavisVantageVueOutdoorTemperature.getStateAs(QuantityType).toUnit('°F').doubleValue,
'rainin' -> DavisVantageVueRainCurrentHour.getStateAs(QuantityType).toUnit('in').doubleValue, 'rainin' -> DavisVantageVueRainCurrentHour.getStateAs(QuantityType).toUnit('in').doubleValue,
'dailyrainin' -> DavisVantageVueRainToday.getStateAs(QuantityType).toUnit('in').doubleValue,
'baromin' -> MeteoStickPressure.getStateAs(QuantityType).toUnit('inHg').doubleValue, 'baromin' -> MeteoStickPressure.getStateAs(QuantityType).toUnit('inHg').doubleValue,
'softwaretype' -> 'openHAB 2.4') 'softwaretype' -> 'openHAB 2.4')

View File

@ -38,6 +38,7 @@ public class MeteostickBindingConstants {
public static final String CHANNEL_RAIN_RAW = "rain-raw"; public static final String CHANNEL_RAIN_RAW = "rain-raw";
public static final String CHANNEL_RAIN_CURRENTHOUR = "rain-currenthour"; public static final String CHANNEL_RAIN_CURRENTHOUR = "rain-currenthour";
public static final String CHANNEL_RAIN_LASTHOUR = "rain-lasthour"; public static final String CHANNEL_RAIN_LASTHOUR = "rain-lasthour";
public static final String CHANNEL_RAIN_TODAY = "rain-today";
public static final String CHANNEL_WIND_SPEED = "wind-speed"; public static final String CHANNEL_WIND_SPEED = "wind-speed";
public static final String CHANNEL_WIND_DIRECTION = "wind-direction"; public static final String CHANNEL_WIND_DIRECTION = "wind-direction";
public static final String CHANNEL_WIND_SPEED_LAST2MIN_AVERAGE = "wind-speed-last2min-average"; public static final String CHANNEL_WIND_SPEED_LAST2MIN_AVERAGE = "wind-speed-last2min-average";
@ -51,6 +52,7 @@ public class MeteostickBindingConstants {
public static final String PARAMETER_CHANNEL = "channel"; public static final String PARAMETER_CHANNEL = "channel";
public static final String PARAMETER_SPOON = "spoon"; public static final String PARAMETER_SPOON = "spoon";
public static final String PARAMETER_SPOON_DEFAULT = "0.254"; public static final String PARAMETER_SPOON_DEFAULT = "0.254";
public static final String PARAMETER_WINDVANE = "deltaWindDirection";
// Miscellaneous constants // Miscellaneous constants
public static final long HOUR_IN_SEC = 60 * 60; public static final long HOUR_IN_SEC = 60 * 60;

View File

@ -17,6 +17,7 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.meteostick.internal.handler.MeteostickBridgeHandler; import org.openhab.binding.meteostick.internal.handler.MeteostickBridgeHandler;
import org.openhab.binding.meteostick.internal.handler.MeteostickSensorHandler; import org.openhab.binding.meteostick.internal.handler.MeteostickSensorHandler;
import org.openhab.core.io.transport.serial.SerialPortManager; import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.scheduler.CronScheduler;
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;
@ -41,10 +42,13 @@ public class MeteostickHandlerFactory extends BaseThingHandlerFactory {
private Logger logger = LoggerFactory.getLogger(MeteostickHandlerFactory.class); private Logger logger = LoggerFactory.getLogger(MeteostickHandlerFactory.class);
private final SerialPortManager serialPortManager; private final SerialPortManager serialPortManager;
private final CronScheduler scheduler;
@Activate @Activate
public MeteostickHandlerFactory(final @Reference SerialPortManager serialPortManager) { public MeteostickHandlerFactory(final @Reference SerialPortManager serialPortManager,
final @Reference CronScheduler scheduler) {
this.serialPortManager = serialPortManager; this.serialPortManager = serialPortManager;
this.scheduler = scheduler;
} }
@Override @Override
@ -64,7 +68,7 @@ public class MeteostickHandlerFactory extends BaseThingHandlerFactory {
} }
if (MeteostickSensorHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) { if (MeteostickSensorHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
return new MeteostickSensorHandler(thing); return new MeteostickSensorHandler(thing, scheduler);
} }
return null; return null;

View File

@ -31,6 +31,8 @@ import java.util.concurrent.TimeUnit;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.scheduler.CronScheduler;
import org.openhab.core.scheduler.ScheduledCompletableFuture;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatus;
@ -48,25 +50,33 @@ import org.slf4j.LoggerFactory;
* *
* @author Chris Jackson - Initial contribution * @author Chris Jackson - Initial contribution
* @author John Cocula - Added variable spoon size, UoM, wind stats, bug fixes * @author John Cocula - Added variable spoon size, UoM, wind stats, bug fixes
* @author Cor Hoogendoorn - Added option for wind vanes not facing North and cumulative rainfall for today
*/ */
public class MeteostickSensorHandler extends BaseThingHandler implements MeteostickEventListener { public class MeteostickSensorHandler extends BaseThingHandler implements MeteostickEventListener {
private static final String DAILY_MIDNIGHT = "1 0 0 * * ? *";
private final CronScheduler cronScheduler;
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_DAVIS); public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_DAVIS);
private final Logger logger = LoggerFactory.getLogger(MeteostickSensorHandler.class); private final Logger logger = LoggerFactory.getLogger(MeteostickSensorHandler.class);
private int channel = 0; private int channel = 0;
private int deltawinddir = 0;
private int rainspoonold = -1;
private BigDecimal rainfallToday = BigDecimal.ZERO;
private BigDecimal spoon = new BigDecimal(PARAMETER_SPOON_DEFAULT); private BigDecimal spoon = new BigDecimal(PARAMETER_SPOON_DEFAULT);
private MeteostickBridgeHandler bridgeHandler; private MeteostickBridgeHandler bridgeHandler;
private RainHistory rainHistory = new RainHistory(HOUR_IN_MSEC); private RainHistory rainHistory = new RainHistory(HOUR_IN_MSEC);
private WindHistory windHistory = new WindHistory(2 * 60 * 1000); // 2 minutes private WindHistory windHistory = new WindHistory(2 * 60 * 1000); // 2 minutes
private ScheduledFuture<?> rainHourlyJob; private ScheduledFuture<?> rainHourlyJob;
private ScheduledCompletableFuture<?> rainMidnightJob;
private ScheduledFuture<?> wind2MinJob; private ScheduledFuture<?> wind2MinJob;
private ScheduledFuture<?> offlineTimerJob; private ScheduledFuture<?> offlineTimerJob;
private Date lastData; private Date lastData;
public MeteostickSensorHandler(Thing thing) { public MeteostickSensorHandler(Thing thing, final CronScheduler scheduler) {
super(thing); super(thing);
this.cronScheduler = scheduler;
} }
@Override @Override
@ -79,10 +89,14 @@ public class MeteostickSensorHandler extends BaseThingHandler implements Meteost
if (spoon == null) { if (spoon == null) {
spoon = new BigDecimal(PARAMETER_SPOON_DEFAULT); spoon = new BigDecimal(PARAMETER_SPOON_DEFAULT);
} }
logger.debug("Initializing MeteoStick handler - Channel {}, Spoon size {} mm.", channel, spoon);
deltawinddir = ((BigDecimal) getConfig().get(PARAMETER_WINDVANE)).intValue();
logger.debug("Initializing MeteoStick handler - Channel {}, Spoon size {} mm, Wind vane offset {} °", channel,
spoon, deltawinddir);
Runnable rainRunnable = () -> { Runnable rainRunnable = () -> {
BigDecimal rainfall = rainHistory.getTotal(spoon); BigDecimal rainfall = rainHistory.getTotal();
rainfall.setScale(1, RoundingMode.DOWN); rainfall.setScale(1, RoundingMode.DOWN);
updateState(new ChannelUID(getThing().getUID(), CHANNEL_RAIN_LASTHOUR), updateState(new ChannelUID(getThing().getUID(), CHANNEL_RAIN_LASTHOUR),
new QuantityType<>(rainfall, MILLI(METRE))); new QuantityType<>(rainfall, MILLI(METRE)));
@ -92,6 +106,9 @@ public class MeteostickSensorHandler extends BaseThingHandler implements Meteost
long start = HOUR_IN_SEC - ((System.currentTimeMillis() % HOUR_IN_MSEC) / 1000); long start = HOUR_IN_SEC - ((System.currentTimeMillis() % HOUR_IN_MSEC) / 1000);
rainHourlyJob = scheduler.scheduleWithFixedDelay(rainRunnable, start, HOUR_IN_SEC, TimeUnit.SECONDS); rainHourlyJob = scheduler.scheduleWithFixedDelay(rainRunnable, start, HOUR_IN_SEC, TimeUnit.SECONDS);
// Scheduling a job at midnight to reset today's rainfall to 0
rainMidnightJob = cronScheduler.schedule(this::dailyJob, DAILY_MIDNIGHT);
Runnable windRunnable = () -> { Runnable windRunnable = () -> {
WindStats stats = windHistory.getStats(); WindStats stats = windHistory.getStats();
updateState(new ChannelUID(getThing().getUID(), CHANNEL_WIND_SPEED_LAST2MIN_AVERAGE), updateState(new ChannelUID(getThing().getUID(), CHANNEL_WIND_SPEED_LAST2MIN_AVERAGE),
@ -114,6 +131,10 @@ public class MeteostickSensorHandler extends BaseThingHandler implements Meteost
rainHourlyJob.cancel(true); rainHourlyJob.cancel(true);
} }
if (rainMidnightJob != null) {
rainMidnightJob.cancel(true);
}
if (wind2MinJob != null) { if (wind2MinJob != null) {
wind2MinJob.cancel(true); wind2MinJob.cancel(true);
} }
@ -193,18 +214,43 @@ public class MeteostickSensorHandler extends BaseThingHandler implements Meteost
processSignalStrength(data[3]); processSignalStrength(data[3]);
processBattery(data.length == 5); processBattery(data.length == 5);
rainHistory.put(rain); rain &= 0x7F;
int totalspoon = 0;
if (rainspoonold < 0) {
rainspoonold = rain;
}
if (rain < rainspoonold) {
totalspoon = 128 - rainspoonold + rain;
} else {
totalspoon = rain - rainspoonold;
}
BigDecimal rainfall = rainHistory.getTotal(spoon); BigDecimal rainincrease = BigDecimal.valueOf(totalspoon).multiply(spoon);
rainHistory.put(rainincrease);
BigDecimal rainfall = rainHistory.getTotal();
rainfall.setScale(1, RoundingMode.DOWN); rainfall.setScale(1, RoundingMode.DOWN);
updateState(new ChannelUID(getThing().getUID(), CHANNEL_RAIN_CURRENTHOUR), updateState(new ChannelUID(getThing().getUID(), CHANNEL_RAIN_CURRENTHOUR),
new QuantityType<>(rainfall, MILLI(METRE))); new QuantityType<>(rainfall, MILLI(METRE)));
rainfallToday = rainfallToday.add(rainincrease);
rainfallToday.setScale(1, RoundingMode.DOWN);
updateState(new ChannelUID(getThing().getUID(), CHANNEL_RAIN_TODAY),
new QuantityType<>(rainfallToday, MILLI(METRE)));
rainspoonold = rain;
break; break;
case "W": // Wind case "W": // Wind
BigDecimal windSpeed = new BigDecimal(data[2]); BigDecimal windSpeed = new BigDecimal(data[2]);
int windDirection = Integer.parseInt(data[3]); int windDirection = Integer.parseInt(data[3]);
updateState(new ChannelUID(getThing().getUID(), CHANNEL_WIND_SPEED), updateState(new ChannelUID(getThing().getUID(), CHANNEL_WIND_SPEED),
new QuantityType<>(windSpeed, METRE_PER_SECOND)); new QuantityType<>(windSpeed, METRE_PER_SECOND));
if (deltawinddir != 0) {
if (windDirection < (360 - deltawinddir)) {
windDirection += deltawinddir;
} else {
windDirection -= (360 - deltawinddir);
}
}
updateState(new ChannelUID(getThing().getUID(), CHANNEL_WIND_DIRECTION), updateState(new ChannelUID(getThing().getUID(), CHANNEL_WIND_DIRECTION),
new QuantityType<>(windDirection, DEGREE_ANGLE)); new QuantityType<>(windDirection, DEGREE_ANGLE));
@ -265,43 +311,24 @@ public class MeteostickSensorHandler extends BaseThingHandler implements Meteost
} }
} }
class RainHistory extends SlidingTimeWindow<Integer> { class RainHistory extends SlidingTimeWindow<BigDecimal> {
public RainHistory(long period) { public RainHistory(long period) {
super(period); super(period);
} }
public BigDecimal getTotal(BigDecimal spoon) { public BigDecimal getTotal() {
removeOldEntries(); removeOldEntries();
BigDecimal raintotalmap = BigDecimal.ZERO;
int least = -1;
int total = 0;
synchronized (storage) { synchronized (storage) {
for (int value : storage.values()) { for (BigDecimal value : storage.values()) {
/* raintotalmap = raintotalmap.add(value);
* Rain counters have been seen to wrap at 127 and also at 255.
* The Meteostick documentation only mentions 255 at the time of
* this writing. This potential difference is solved by having
* all rain counters wrap at 127 (0x7F) by removing the high bit.
*/
value &= 0x7F;
if (least == -1) {
least = value;
continue;
}
if (value < least) {
total = 128 - least + value;
} else {
total = value - least;
}
} }
} }
return BigDecimal.valueOf(total).multiply(spoon); return raintotalmap;
} }
} }
@ -392,4 +419,11 @@ public class MeteostickSensorHandler extends BaseThingHandler implements Meteost
// Scheduling a job on each hour to update the last hour rainfall // Scheduling a job on each hour to update the last hour rainfall
offlineTimerJob = scheduler.schedule(pollingRunnable, 90, TimeUnit.SECONDS); offlineTimerJob = scheduler.schedule(pollingRunnable, 90, TimeUnit.SECONDS);
} }
private void dailyJob() {
// Daily job to reset the daily rain accumulation
rainfallToday = BigDecimal.ZERO;
updateState(new ChannelUID(getThing().getUID(), CHANNEL_RAIN_TODAY),
new QuantityType<>(rainfallToday, MILLI(METRE)));
}
} }

View File

@ -32,6 +32,8 @@ thing-type.config.meteostick.meteostick_davis_iss.channel.option.5 = Channel 5
thing-type.config.meteostick.meteostick_davis_iss.channel.option.6 = Channel 6 thing-type.config.meteostick.meteostick_davis_iss.channel.option.6 = Channel 6
thing-type.config.meteostick.meteostick_davis_iss.channel.option.7 = Channel 7 thing-type.config.meteostick.meteostick_davis_iss.channel.option.7 = Channel 7
thing-type.config.meteostick.meteostick_davis_iss.channel.option.8 = Channel 8 thing-type.config.meteostick.meteostick_davis_iss.channel.option.8 = Channel 8
thing-type.config.meteostick.meteostick_davis_iss.deltaWindDirection.label = Wind Vane Direction
thing-type.config.meteostick.meteostick_davis_iss.deltaWindDirection.description = Specifies the direction that the wind vane's North is actually pointed towards (0 to 359)
thing-type.config.meteostick.meteostick_davis_iss.spoon.label = Spoon thing-type.config.meteostick.meteostick_davis_iss.spoon.label = Spoon
thing-type.config.meteostick.meteostick_davis_iss.spoon.description = Specifies the amount of rain needed to tip spoon thing-type.config.meteostick.meteostick_davis_iss.spoon.description = Specifies the amount of rain needed to tip spoon
@ -51,6 +53,8 @@ channel-type.meteostick.rain-lasthour.label = Rainfall (previous Hour)
channel-type.meteostick.rain-lasthour.description = Rainfall in the previous hour channel-type.meteostick.rain-lasthour.description = Rainfall in the previous hour
channel-type.meteostick.rain-raw.label = Rainfall (Raw) channel-type.meteostick.rain-raw.label = Rainfall (Raw)
channel-type.meteostick.rain-raw.description = A counter between 0 and 255 in spoon-sized steps channel-type.meteostick.rain-raw.description = A counter between 0 and 255 in spoon-sized steps
channel-type.meteostick.rain-today.label = Rainfall Today
channel-type.meteostick.rain-today.description = Total rainfall today
channel-type.meteostick.solar-power.label = Solar Power channel-type.meteostick.solar-power.label = Solar Power
channel-type.meteostick.solar-power.description = Solar panel power percentage channel-type.meteostick.solar-power.description = Solar panel power percentage
channel-type.meteostick.wind-direction-last2min-average.label = Wind Direction (Average) channel-type.meteostick.wind-direction-last2min-average.label = Wind Direction (Average)

View File

@ -52,6 +52,7 @@
<channel id="rain-raw" typeId="rain-raw"/> <channel id="rain-raw" typeId="rain-raw"/>
<channel id="rain-currenthour" typeId="rain-currenthour"/> <channel id="rain-currenthour" typeId="rain-currenthour"/>
<channel id="rain-lasthour" typeId="rain-lasthour"/> <channel id="rain-lasthour" typeId="rain-lasthour"/>
<channel id="rain-today" typeId="rain-today"/>
<channel id="solar-power" typeId="solar-power"/> <channel id="solar-power" typeId="solar-power"/>
<channel id="signal-strength" typeId="system.signal-strength"/> <channel id="signal-strength" typeId="system.signal-strength"/>
<channel id="low-battery" typeId="system.low-battery"/> <channel id="low-battery" typeId="system.low-battery"/>
@ -79,6 +80,13 @@
<default>0.254</default> <default>0.254</default>
<unitLabel>mm</unitLabel> <unitLabel>mm</unitLabel>
</parameter> </parameter>
<parameter name="deltaWindDirection" type="integer" required="false" min="0" max="359">
<label>Wind Vane Direction</label>
<description>Specifies the direction that the wind vane's North is actually pointed towards (0 to 359)</description>
<default>0</default>
<unitLabel>°</unitLabel>
</parameter>
</config-description> </config-description>
</thing-type> </thing-type>
@ -190,6 +198,15 @@
</state> </state>
</channel-type> </channel-type>
<channel-type id="rain-today">
<item-type>Number:Length</item-type>
<label>Rainfall Today</label>
<description>Total rainfall today</description>
<category>Rain</category>
<state readOnly="true" pattern="%.1f %unit%">
</state>
</channel-type>
<channel-type id="solar-power"> <channel-type id="solar-power">
<item-type>Number</item-type> <item-type>Number</item-type>
<label>Solar Power</label> <label>Solar Power</label>