这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on May 17, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.openhab.core.binding.BindingProvider;
import org.openhab.binding.netatmo.internal.NetatmoMeasureType;
import org.openhab.binding.netatmo.internal.NetatmoScale;

/**
* This interface is implemented by classes that can provide mapping information
Expand All @@ -19,6 +20,7 @@
* taken into account.
*
* @author Andreas Brenk
* @author Rob Nielsen
* @since 1.4.0
*/
public interface NetatmoBindingProvider extends BindingProvider {
Expand Down Expand Up @@ -62,4 +64,13 @@ public interface NetatmoBindingProvider extends BindingProvider {
*/
String getModuleId(String itemName);

/**
* Returns the scale to use when querying the Netatmo measure of the given
* {@code itemName}.
*
* @param itemName
* @return the Netatmo scale of the Item identified by {@code itemName} if
* it has a Netatmo binding, <code>null</code> otherwise
*/
NetatmoScale getNetatmoScale(String itemName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
import static org.openhab.binding.netatmo.internal.messages.MeasurementRequest.createKey;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -118,12 +120,17 @@ protected void execute() {
}

DeviceMeasureValueMap deviceMeasureValueMap = processMeasurements(oauthCredentials);
if (deviceMeasureValueMap == null) {
return;
}

for (final NetatmoBindingProvider provider : this.providers) {
for (final String itemName : provider.getItemNames()) {
final String deviceId = provider.getDeviceId(itemName);
final String moduleId = provider.getModuleId(itemName);
final NetatmoMeasureType measureType = provider
.getMeasureType(itemName);
final NetatmoScale scale = provider.getNetatmoScale(itemName);

State state = null;
switch (measureType) {
Expand Down Expand Up @@ -157,22 +164,60 @@ protected void execute() {
case NOISE:
case PRESSURE:
case RAIN:
final String requestKey = createKey(deviceId,
moduleId);
BigDecimal value = deviceMeasureValueMap.get(
requestKey).get(measureType.getMeasure());
// Protect that sometimes Netatmo returns null where
// numeric value is awaited (issue #1848)
if (value != null) {
if (measureType == NetatmoMeasureType.TEMPERATURE) {
value = unitSystem.convertTemp(value);
} else if (measureType == NetatmoMeasureType.RAIN) {
value = unitSystem.convertRain(value);
} else if (measureType == NetatmoMeasureType.PRESSURE) {
value = pressureUnit.convertPressure(value);
}
case MIN_TEMP:
case MAX_TEMP:
case MIN_HUM:
case MAX_HUM:
case MIN_PRESSURE:
case MAX_PRESSURE:
case MIN_NOISE:
case MAX_NOISE:
case MIN_CO2:
case MAX_CO2:
case SUM_RAIN:
{
BigDecimal value = getValue(
deviceMeasureValueMap, measureType,
createKey(deviceId, moduleId, scale));
// Protect that sometimes Netatmo returns null where
// numeric value is awaited (issue #1848)
if (value != null) {
if (NetatmoMeasureType
.isTemperature(measureType)) {
value = unitSystem.convertTemp(value);
} else if (NetatmoMeasureType
.isRain(measureType)) {
value = unitSystem.convertRain(value);
} else if (NetatmoMeasureType
.isPressure(measureType)) {
value = pressureUnit.convertPressure(value);
}

state = new DecimalType(value);
state = new DecimalType(value);
}
}
break;
case DATE_MIN_TEMP:
case DATE_MAX_TEMP:
case DATE_MIN_HUM:
case DATE_MAX_HUM:
case DATE_MIN_PRESSURE:
case DATE_MAX_PRESSURE:
case DATE_MIN_NOISE:
case DATE_MAX_NOISE:
case DATE_MIN_CO2:
case DATE_MAX_CO2:
{
final BigDecimal value = getValue(
deviceMeasureValueMap, measureType,
createKey(deviceId, moduleId, scale));
if (value != null) {
final Calendar calendar = GregorianCalendar
.getInstance();
calendar.setTimeInMillis(value.longValue() * 1000);

state = new DateTimeType(calendar);
}
}
break;
case BATTERYVP:
Expand Down Expand Up @@ -206,13 +251,16 @@ protected void execute() {
for (Device device : oauthCredentials.deviceListResponse
.getDevices()) {
if (stationPosition == null) {
DecimalType altitude = DecimalType.ZERO;
if (device.getAltitude() != null) {
altitude = new DecimalType(Math.round(unitSystem.
convertAltitude(device.getAltitude())));
}
stationPosition = new PointType(
new DecimalType(
device.getLatitude()),
new DecimalType(device
.getLongitude()),
new DecimalType(Math.round(unitSystem.
convertAltitude(device.getAltitude()))));
new BigDecimal(device.getLatitude()).setScale(6, BigDecimal.ROUND_HALF_UP)),
new DecimalType(new BigDecimal(device.getLongitude()).setScale(6, BigDecimal.ROUND_HALF_UP)),
altitude);
}
if (device.getId().equals(deviceId)) {
switch (measureType) {
Expand Down Expand Up @@ -253,6 +301,13 @@ protected void execute() {
}
}

private BigDecimal getValue(DeviceMeasureValueMap deviceMeasureValueMap,
final NetatmoMeasureType measureType, final String requestKey) {
Map<String, BigDecimal> map = deviceMeasureValueMap.get(requestKey);

return map != null ? map.get(measureType.getMeasure()) : null;
}

static class DeviceMeasureValueMap extends
HashMap<String, Map<String, BigDecimal>> {

Expand All @@ -276,14 +331,20 @@ private DeviceMeasureValueMap processMeasurements(
if (response.isError()) {
final NetatmoError error = response.getError();

if (error.isAccessTokenExpired()) {
if (error.isAccessTokenExpired() || error.isTokenNotVaid()) {
logger.debug("Token is expired or is not valid, refreshing: code = {} message = {}",
error.getCode(), error.getMessage());

oauthCredentials.refreshAccessToken();
execute();

return null;
} else {
logger.error("Error sending measurement request: code = {} message = {}",
error.getCode(), error.getMessage());

throw new NetatmoException(error.getMessage());
}

break; // abort processing measurement requests
} else {
processMeasurementResponse(request, response,
deviceMeasureValueMap);
Expand All @@ -301,10 +362,16 @@ private void processDeviceList(OAuthCredentials oauthCredentials) {
final NetatmoError error = oauthCredentials.deviceListResponse
.getError();

if (error.isAccessTokenExpired()) {
if (error.isAccessTokenExpired() || error.isTokenNotVaid()) {
logger.debug("Token is expired or is not valid, refreshing: code = {} message = {}",
error.getCode(), error.getMessage());

oauthCredentials.refreshAccessToken();
execute();
} else {
logger.error("Error processing device list: code = {} message = {}",
error.getCode(), error.getMessage());

throw new NetatmoException(error.getMessage());
}

Expand Down Expand Up @@ -415,32 +482,40 @@ private Collection<MeasurementRequest> createMeasurementRequests() {

for (final NetatmoBindingProvider provider : this.providers) {
for (final String itemName : provider.getItemNames()) {

final String userid = provider.getUserid(itemName);
final String deviceId = provider.getDeviceId(itemName);
final String moduleId = provider.getModuleId(itemName);
final NetatmoMeasureType measureType = provider
.getMeasureType(itemName);

final String requestKey = createKey(deviceId, moduleId);

switch (measureType) {
case TEMPERATURE:
case CO2:
case HUMIDITY:
case NOISE:
case PRESSURE:
case RAIN:
OAuthCredentials oauthCredentials = getOAuthCredentials(userid);
if (oauthCredentials != null) {
if (!requests.containsKey(requestKey)) {
requests.put(requestKey, new MeasurementRequest(
oauthCredentials.accessToken, deviceId,
moduleId));
}
requests.get(requestKey).addMeasure(measureType);
break;
}
case MIN_TEMP:
case MAX_TEMP:
case MIN_HUM:
case MAX_HUM:
case MIN_PRESSURE:
case MAX_PRESSURE:
case MIN_NOISE:
case MAX_NOISE:
case MIN_CO2:
case MAX_CO2:
case SUM_RAIN:
case DATE_MIN_TEMP:
case DATE_MAX_TEMP:
case DATE_MIN_HUM:
case DATE_MAX_HUM:
case DATE_MIN_PRESSURE:
case DATE_MAX_PRESSURE:
case DATE_MIN_NOISE:
case DATE_MAX_NOISE:
case DATE_MIN_CO2:
case DATE_MAX_CO2:
final NetatmoScale scale = provider.getNetatmoScale(itemName);
addMeasurement(requests, provider, itemName, measureType, scale);
break;
default:
break;
}
Expand All @@ -450,23 +525,47 @@ private Collection<MeasurementRequest> createMeasurementRequests() {
return requests.values();
}

private void addMeasurement(final Map<String, MeasurementRequest> requests,
final NetatmoBindingProvider provider, final String itemName,
final NetatmoMeasureType measureType, final NetatmoScale scale) {

final String userid = provider.getUserid(itemName);
final OAuthCredentials oauthCredentials = getOAuthCredentials(userid);

if (oauthCredentials != null) {
final String deviceId = provider.getDeviceId(itemName);
final String moduleId = provider.getModuleId(itemName);
final String requestKey = createKey(deviceId, moduleId, scale);

if (!requests.containsKey(requestKey)) {
requests.put(requestKey, new MeasurementRequest(
oauthCredentials.accessToken, deviceId,
moduleId, scale));
}
requests.get(requestKey).addMeasure(measureType);
}
}

private void processMeasurementResponse(final MeasurementRequest request,
final MeasurementResponse response,
DeviceMeasureValueMap deviceMeasureValueMap) {
final List<BigDecimal> values = response.getBody().get(0).getValues()
.get(0);
final Map<String, BigDecimal> valueMap = new HashMap<String, BigDecimal>();

Map<String, BigDecimal> valueMap = deviceMeasureValueMap.get(request.getKey());
if (valueMap == null) {
valueMap = new HashMap<String, BigDecimal>();

deviceMeasureValueMap.put(request.getKey(), valueMap);
deviceMeasureValueMap.timeStamp = new DateTimeType(response.getTimeStamp());
}

int index = 0;
for (final String measure : request.getMeasures()) {
final BigDecimal value = values.get(index);
valueMap.put(measure, value);
index++;
}

deviceMeasureValueMap.put(request.getKey(), valueMap);
deviceMeasureValueMap.timeStamp = new DateTimeType(
response.getTimeStamp());
}

/**
Expand Down Expand Up @@ -639,6 +738,14 @@ public void refreshAccessToken() {
final RefreshTokenResponse response = request.execute();
logger.debug("Response: {}", response);

if (response == null) {
throw new NetatmoException("Could not refresh access token! If you see "
+ "'Fatal transport error: javax.net.ssl.SSLHandshakeException' "
+ "above. You need to install the StartCom CA certificate and restart openHAB. "
+ "See https://github.com/openhab/openhab/wiki/Netatmo-Binding#missing-certificate-authority "
+ "for more information.");
}

this.accessToken = response.getAccessToken();

deviceListRequest = new DeviceListRequest(this.accessToken);
Expand Down
Loading