Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ipobserver] Weather station binding, Initial contribution. #10567

Merged
merged 37 commits into from
Jul 17, 2021
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d542b84
Bulk updated to UOM.
Skinah Mar 29, 2021
6b73e5b
ipObserver creation
Skinah Mar 22, 2021
a1a7d9f
Bulk updated to UOM.
Skinah Mar 29, 2021
ef5aff1
channel fixup for UOM.
Skinah Mar 30, 2021
40498a8
improve UOM.
Skinah Mar 31, 2021
377b022
updates
Skinah Apr 1, 2021
d87271c
Battery ch fixed.
Skinah Apr 1, 2021
2dc9c2d
Fix time channels.
Skinah Apr 2, 2021
5186dd7
readme update and remove %unit% from rain channels.
Skinah Apr 23, 2021
596cc7f
readme fixup.
Skinah Apr 24, 2021
70ac771
edit global files.
Skinah Apr 24, 2021
4b5c1e3
Fix merge conflicts.
Skinah Apr 24, 2021
6d64f47
fix up build issues.
Skinah Apr 24, 2021
f53020f
remove reboot channel.
Skinah Apr 24, 2021
37d1f7f
readme fixup.
Skinah Apr 24, 2021
af64543
Rename channels to put kind first.
Skinah May 13, 2021
09082aa
update to build on latest main.
Skinah May 16, 2021
ed5c196
Add support for outBatt1
Skinah May 16, 2021
93e86cf
Added auto discovery.
Skinah Jun 6, 2021
eedfdca
add bundle to POM.
Skinah Jun 6, 2021
6fde471
newline added.
Skinah Jun 6, 2021
992fa4f
Fix bug in discovery.
Skinah Jun 6, 2021
452919e
Added tags
Skinah Jul 3, 2021
4fb5837
update to 3.2.0-SNAPSHOT
Skinah Jul 3, 2021
4f41326
Update bundles/org.openhab.binding.ipobserver/src/main/resources/OH-I…
Skinah Jul 13, 2021
b2695a6
Update bundles/org.openhab.binding.ipobserver/src/main/resources/OH-I…
Skinah Jul 13, 2021
7362c33
Clean up channels
Skinah Jul 13, 2021
6c5fe21
Update binding description.
Skinah Jul 13, 2021
62c86c6
Fix jsoup suggestions.
Skinah Jul 13, 2021
b97596c
Update bundles/org.openhab.binding.ipobserver/src/main/java/org/openh…
Skinah Jul 13, 2021
e147580
Update bundles/org.openhab.binding.ipobserver/src/main/resources/OH-I…
Skinah Jul 13, 2021
df36c89
Removed nullable.
Skinah Jul 13, 2021
da25254
Improvements
Skinah Jul 15, 2021
6b931c4
Fix compiler warnings
Skinah Jul 15, 2021
287f158
Change to datetime
Skinah Jul 15, 2021
2b13935
change to use system channels.
Skinah Jul 16, 2021
c5babae
Move to Number:Intensity for solar
Skinah Jul 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
/bundles/org.openhab.binding.insteon/ @robnielsen
/bundles/org.openhab.binding.intesis/ @hmerk
/bundles/org.openhab.binding.ipcamera/ @Skinah
/bundles/org.openhab.binding.ipobserver/ @Skinah
/bundles/org.openhab.binding.ipp/ @peuter
/bundles/org.openhab.binding.irobot/ @Sonic-Amiga
/bundles/org.openhab.binding.irtrans/ @kgoderis
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,11 @@
<artifactId>org.openhab.binding.ipcamera</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.ipobserver</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.ipp</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.ipobserver/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code
Skinah marked this conversation as resolved.
Show resolved Hide resolved

https://github.com/openhab/openhab-addons
54 changes: 54 additions & 0 deletions bundles/org.openhab.binding.ipobserver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# IpObserver Binding

This binding is for any weather station that sends data to an IP Observer module.
The weather stations that do this are made by a company in China called `Fine Offset` and then re-branded by many distribution companies around the world.
Some of the brands include Aercus (433mhz), Ambient Weather (915mhz), Frogitt, Misol (433mhz), Pantech (433mhz), Sainlogic and many more.
Whilst Ambient Weather has it own cloud based binding, the other brands will not work with that binding and Ambient Weather do not sell outside of the United States.
This binding works fully offline and uses local scraping of the weather station data at 12 second resolution if you wish and is easy to setup.
The other binding worth mentioning is the weather underground binding that allows the data to be intercepted on its way to WU, however many of the weather stations do not allow the redirection of the WU data and require you to know how to do redirections with a custom DNS server on your network.
This binding is by far the easiest method and works for all the brands and will not stop the data still being sent to WU if you wish to do both at the same time.
If your weather station came with a LCD screen instead of the IP Observer, you can add on the unit and the LCD screen will still work in parallel as the RF data is sent 1 way from the outdoor unit to the inside screens and IP Observer units.

## Supported Things

There is only one thing that can be added and is called `weatherstation`.

## Discovery

Auto discovery is supported and may take a while to complete as it scans all IP addresses on your network one by one.

## Thing Configuration

| Parameter | Required | Description |
|-|-|-|
| `address` | Y | Hostname or IP for the IP Observer |
| `pollTime` | Y | Time in seconds between each Scan of the livedata.htm from the IP Observer |
| `autoReboot` | Y | Time in milliseconds to wait for a reply before rebooting the IP Observer. A value of 0 disables this feature allowing you to manually trigger or use a rule to handle the reboots. |

## Channels

| channel | type | description |
|-----------------------|-----------------------|------------------------------|
| temperatureIndoor | Number:Temperature | The temperature indoors. |
| temperatureOutdoor | Number:Temperature | The temperature outdoors. |
| humidityIndoor | Number:Dimensionless | The humidity indoors. |
| humidityOutdoor | Number:Dimensionless | The humidity outdoors. |
| pressureAbsolute | Number:Pressure | The atmospheric pressure directly measured by the sensor. |
| pressureRelative | Number:Pressure | The pressure adjusted to sea level to allow easier comparisons between different locations. |
| windDirection | Number:Angle | The angle in degrees that the wind is comming from. |
| windAverageSpeed | Number:Speed | The average wind speed. |
| windSpeed | Number:Speed | The exact wind speed. Not all stations send this data. |
| windGust | Number:Speed | The recent wind gust speed. |
| windMaxGust | Number:Speed | The recent max wind gust speed. |
| solarRadiation | Number | Solar radiation. |
| uv | Number | UV measurement. |
Skinah marked this conversation as resolved.
Show resolved Hide resolved
| uvIndex | Number | The UV index. |
| rainHourlyRate | Number:Length | The amount of rain that will fall, if it continues to fall at the same rate for an hour. Measures how heavy the current rain is falling. |
| rainToday | Number:Length | Amount of rain since 12:00am. |
| rainForWeek | Number:Length | Amount of rain for the week. |
| rainForMonth | Number:Length | Amount of rain for the month. |
| rainForYear | Number:Length | Amount of rain for the year. |
| batteryIndoor | String | Battery status, if it is low or normal. |
| batteryOutdoor | String | Battery status, if it is low or normal. |
Skinah marked this conversation as resolved.
Show resolved Hide resolved
| responseTime | Number:Time | How long it took the weather station to reply to a request for the data. |
| lastUpdatedTime | String | The time scraped from the weather station when it last read the sensors. |
Skinah marked this conversation as resolved.
Show resolved Hide resolved
24 changes: 24 additions & 0 deletions bundles/org.openhab.binding.ipobserver/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>3.2.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.ipobserver</artifactId>

<name>openHAB Add-ons :: Bundles :: IpObserver Binding</name>
<dependencies>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
<scope>compile</scope>
Skinah marked this conversation as resolved.
Show resolved Hide resolved
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.ipobserver-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
<feature name="openhab-binding-ipobserver" description="IpObserver Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle dependency="true">mvn:org.jsoup/jsoup/1.8.3</bundle>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.ipobserver/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright (c) 2010-2021 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.ipobserver.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;

/**
* The {@link IpObserverBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Matthew Skinner - Initial contribution
*/
@NonNullByDefault
public class IpObserverBindingConstants {
public static final String BINDING_ID = "ipobserver";
public static final String REBOOT_URL = "/msgreboot.htm";
public static final String LIVE_DATA_URL = "/livedata.htm";
public static final String STATION_SETTINGS_URL = "/station.htm";
public static final int DISCOVERY_THREAD_POOL_SIZE = 15;

// List of all Thing Type UIDs
public static final ThingTypeUID THING_WEATHER_STATION = new ThingTypeUID(BINDING_ID, "weatherstation");

// List of all Channel ids
public static final String TEMP_INDOOR = "temperatureIndoor";
public static final String TEMP_OUTDOOR = "temperatureOutdoor";
public static final String INDOOR_HUMIDITY = "humidityIndoor";
public static final String OUTDOOR_HUMIDITY = "humidityOutdoor";
public static final String ABS_PRESSURE = "pressureAbsolute";
public static final String REL_PRESSURE = "pressureRelative";
public static final String WIND_DIRECTION = "windDirection";
public static final String WIND_AVERAGE_SPEED = "windAverageSpeed";
public static final String WIND_SPEED = "windSpeed";
public static final String WIND_GUST = "windGust";
public static final String WIND_MAX_GUST = "windMaxGust";
public static final String SOLAR_RADIATION = "solarRadiation";
public static final String UV = "uv";
public static final String UV_INDEX = "uvIndex";
public static final String HOURLY_RAIN_RATE = "rainHourlyRate";
public static final String DAILY_RAIN = "rainToday";
public static final String WEEKLY_RAIN = "rainForWeek";
public static final String MONTHLY_RAIN = "rainForMonth";
public static final String YEARLY_RAIN = "rainForYear";
public static final String INDOOR_BATTERY = "batteryIndoor";
public static final String OUTDOOR_BATTERY = "batteryOutdoor";
public static final String RESPONSE_TIME = "responseTime";
public static final String LAST_UPDATED_TIME = "lastUpdatedTime";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2010-2021 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.ipobserver.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* The {@link IpObserverConfiguration} class contains fields mapping thing configuration parameters.
*
* @author Matthew Skinner - Initial contribution
*/
@NonNullByDefault
public class IpObserverConfiguration {
// bindings config
public String address = "";
public int pollTime = 20;
public int autoReboot = 2000;

// Config settings parsed from weather station.
public boolean imperialTemperature = false;
public boolean imperialRain = false;
// 0=lux, 1=w/m2, 2=fc
public String solarUnit = "0";
// 0=m/s, 1=km/h, 2=ft/s, 3=bft, 4=mph, 5=knot
public String windUnit = "0";
// 0=hpa, 1=inhg, 2=mmhg
public String pressureUnit = "0";
Skinah marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright (c) 2010-2021 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.ipobserver.internal;

import static org.openhab.binding.ipobserver.internal.IpObserverBindingConstants.LIVE_DATA_URL;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;

/**
* The {@link IpObserverDiscoveryJob} class allows auto discovery of
* devices for a single IP address. This is used
* for threading to make discovery faster.
*
* @author Matthew Skinner - Initial contribution
*/
@NonNullByDefault
public class IpObserverDiscoveryJob implements Runnable {
private IpObserverDiscoveryService discoveryClass;
private String ipAddress;

public IpObserverDiscoveryJob(IpObserverDiscoveryService service, String ip) {
this.discoveryClass = service;
this.ipAddress = ip;
}

@Override
public void run() {
if (isIpObserverDevice(this.ipAddress)) {
discoveryClass.submitDiscoveryResults(this.ipAddress);
}
}

private boolean isIpObserverDevice(String ip) {
Request request = discoveryClass.getHttpClient().newRequest("http://" + ip + LIVE_DATA_URL);
request.method(HttpMethod.GET).timeout(5, TimeUnit.SECONDS).header(HttpHeader.ACCEPT_ENCODING, "gzip");
ContentResponse contentResponse;
try {
contentResponse = request.send();
if (contentResponse.getStatus() == 200 && contentResponse.getContentAsString().contains("livedata.htm")) {
return true;
}
} catch (InterruptedException | TimeoutException | ExecutionException e) {
}
return false;
}
}
Loading