/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.netatmo.internal.weather;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.openhab.binding.netatmo.internal.messages.AbstractMessagePart;
import org.openhab.binding.netatmo.internal.messages.AbstractResponse;
/**
* Java Bean to represent a JSON response to a <code>getstationsdata</code> API
* method call.
* <p>
* Sample response:
*
* <pre>
* {
* "body": {
* "devices": [
* {
* "_id": "70:ee:50:00:00:14",
* "co2_calibrating": false,
* "firmware": 91,
* "last_status_store": 1441872001,
* "last_upgrade": 1440507643,
* "module_name": "ind",
* "modules": [
* {
* "_id": "05:00:00:00:00:14",
* "module_name": "Pluie",
* "type": "NAModule3",
* "firmware": 91,
* "last_message": 1437990885,
* "last_seen": 1437990885,
* "rf_status": 40,
* "battery_vp": 4103,
* "dashboard_data": {
* "time_utc": 1437990885,
* "Rain": 0.101
* },
* "data_type": [
* "Rain"
* ]
* },
* ],
* "place": {
* "altitude": 30.478512648583,
* "city": "Saint-Denis",
* "country": "FR",
* "improveLocProposed": true,
* "location": [
* 2.384033203125,
* 48.936934954094
* ],
* "timezone": "Europe/Paris"
* },
* "station_name": "Station",
* "type": "NAMain",
* "wifi_status": 109,
* "dashboard_data": {
* "AbsolutePressure": 929.4,
* "time_utc": 1441872001,
* "Noise": 110,
* "Temperature": 3.2,
* "Humidity": 60,
* "Pressure": 929.4,
* "CO2": 4852,
* "date_max_temp": 1441850941,
* "date_min_temp": 1441862941,
* "min_temp": -39.5,
* "max_temp": 79.5
* },
* "data_type": [
* "Temperature",
* "CO2",
* "Humidity",
* "Noise",
* "Pressure"
* ]
* }
* ],
* "user": {
* "mail": "toto@netatmo.com",
* "administrative": {
* "reg_locale": "en-US",
* "lang": "en-US",
* "unit": 1,
* "windunit": 1,
* "pressureunit": 1,
* "feel_like_algo": 1
* }
* }
* },
* "status": "ok",
* "time_exec": 0.36015892028809,
* "time_server": 1441872018
* }
* </pre>
*
* @author Rob Nielsen
* @since 1.8.0
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class GetStationsDataResponse extends AbstractResponse {
/**
* <code>type</code> constant of the main indoor station.
*/
@SuppressWarnings("unused")
private static final String TYPE_MAIN = "NAMain";
/**
* <code>type</code> constant of the outdoor module
*/
private static final String TYPE_MODULE_1 = "NAModule1";
/**
* <code>type</code> constant of the wind gauge module
*/
private static final String TYPE_MODULE_2 = "NAModule2";
/**
* <code>type</code> constant of the rain gauge module
*/
private static final String TYPE_MODULE_3 = "NAModule3";
/**
* <code>type</code> constant of the additional indoor module
*/
@SuppressWarnings("unused")
private static final String TYPE_MODULE_4 = "NAModule4";
/**
* <code>type</code> constant of the thermostat relay/plug
*/
@SuppressWarnings("unused")
private static final String TYPE_PLUG = "NAPlug";
/**
* <code>type</code> constant of the thermostat module
*/
@SuppressWarnings("unused")
private static final String TYPE_THERM_1 = "NATherm1";
/**
* <code>wifi_status</code> threshold constant: bad signal
*/
private static final int WIFI_STATUS_BAD_SIGNAL = 86;
/**
* <code>wifi_status</code> threshold constant: middle quality signal
*/
private static final int WIFI_STATUS_MIDDLE_QUALITY_SIGNAL = 71;
/**
* <code>wifi_status</code> threshold constant: good signal
*/
private static final int WIFI_STATUS_GOOD_SIGNAL = 56;
/**
* <code>rf_status</code> threshold constant: low signal
*/
private static final int RF_STATUS_LOW_SIGNAL = 90;
/**
* <code>rf_status</code> threshold constant: medium signal
*/
private static final int RF_STATUS_MEDIUM_SIGNAL = 80;
/**
* <code>rf_status</code> threshold constant: high signal
*/
private static final int RF_STATUS_HIGH_SIGNAL = 70;
/**
* <code>rf_status</code> threshold constant: full signal
*/
private static final int RF_STATUS_FULL_SIGNAL = 60;
/**
* <code>battery_vp</code> max value for type NAModule1: 6000
*/
private static final int BATTERY_MODULE_1_RANGE_MAX = 6000;
/**
* <code>battery_vp</code> min value for type NAModule1: 3600
*/
private static final int BATTERY_MODULE_1_RANGE_MIN = 3600;
/**
* <code>battery_vp</code> threshold for type NAModule1: full
*/
private static final int BATTERY_MODULE_1_FULL = 5500;
/**
* <code>battery_vp</code> threshold for type NAModule1: high
*/
private static final int BATTERY_MODULE_1_HIGH = 5000;
/**
* <code>battery_vp</code> threshold for type NAModule1: medium
*/
private static final int BATTERY_MODULE_1_MEDIUM = 4500;
/**
* <code>battery_vp</code> threshold for type NAModule1: low, otherwise
* verylow
*/
private static final int BATTERY_MODULE_1_LOW = 4000;
/**
* <code>battery_vp</code> max value for type NAModule2: 6000
*/
private static final int BATTERY_MODULE_2_RANGE_MAX = 6000;
/**
* <code>battery_vp</code> min value for type NAModule2: 3950
*/
private static final int BATTERY_MODULE_2_RANGE_MIN = 3950;
/**
* <code>battery_vp</code> threshold for type NAModule2: full
*/
private static final int BATTERY_MODULE_2_FULL = 5590;
/**
* <code>battery_vp</code> threshold for type NAModule2: high
*/
private static final int BATTERY_MODULE_2_HIGH = 5180;
/**
* <code>battery_vp</code> threshold for type NAModule2: medium
*/
private static final int BATTERY_MODULE_2_MEDIUM = 4770;
/**
* <code>battery_vp</code> threshold for type NAModule2: low, otherwise
* verylow
*/
private static final int BATTERY_MODULE_2_LOW = 4360;
/**
* <code>battery_vp</code> max value for type NAModule3: 6000
*/
private static final int BATTERY_MODULE_3_RANGE_MAX = 6000;
/**
* <code>battery_vp</code> min value for type NAModule3: 3600
*/
private static final int BATTERY_MODULE_3_RANGE_MIN = 3600;
/**
* <code>battery_vp</code> threshold for type NAModule3: full
*/
private static final int BATTERY_MODULE_3_FULL = 5500;
/**
* <code>battery_vp</code> threshold for type NAModule3: high
*/
private static final int BATTERY_MODULE_3_HIGH = 5000;
/**
* <code>battery_vp</code> threshold for type NAModule3: medium
*/
private static final int BATTERY_MODULE_3_MEDIUM = 4500;
/**
* <code>battery_vp</code> threshold for type NAModule3: low, otherwise
* verylow
*/
private static final int BATTERY_MODULE_3_LOW = 4000;
/**
* <code>battery_vp</code> max value for type NAModule4: 6000
*/
private static final int BATTERY_MODULE_4_RANGE_MAX = 6000;
/**
* <code>battery_vp</code> min value for type NAModule4: 4200
*/
private static final int BATTERY_MODULE_4_RANGE_MIN = 4200;
/**
* <code>battery_vp</code> threshold for type NAModule4: full
*/
private static final int BATTERY_MODULE_4_FULL = 5640;
/**
* <code>battery_vp</code> threshold for type NAModule4: high
*/
private static final int BATTERY_MODULE_4_HIGH = 5280;
/**
* <code>battery_vp</code> threshold for type NAModule4: medium
*/
private static final int BATTERY_MODULE_4_MEDIUM = 4920;
/**
* <code>battery_vp</code> threshold for type NAModule4: low, otherwise
* verylow
*/
private static final int BATTERY_MODULE_4_LOW = 4560;
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Body extends AbstractMessagePart {
private List<Device> devices;
@JsonProperty("devices")
public List<Device> getDevices() {
return this.devices;
}
@Override
public String toString() {
final ToStringBuilder builder = createToStringBuilder();
builder.appendSuper(super.toString());
builder.append("devices", this.devices);
return builder.toString();
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Device extends AbstractMessagePart {
private String id;
private Boolean co2Calibrating;
private Integer firmware;
private Date lastStatusStore;
private Date lastUpgrade;
private String moduleName;
private List<Module> modules;
private Place place;
private String stationName;
private String type;
private Integer wifiStatus;
private List<String> measurements;
/**
* "_id": "70:ee:50:00:00:14"
*/
@JsonProperty("_id")
public String getId() {
return this.id;
}
/**
* "co2_calibrating": false
*/
@JsonProperty("co2_calibrating")
public Boolean isCo2Calibrating() {
return this.co2Calibrating;
}
/**
* "firmware": 91
*/
@JsonProperty("firmware")
public Integer getFirmware() {
return this.firmware;
}
/**
* "last_status_store": 1441872001
*/
@JsonProperty("last_status_store")
public Date getLastStatusStore() {
return this.lastStatusStore;
}
/**
* "last_upgrade": 1440507643
*/
@JsonProperty("last_upgrade")
public Date getLastUpgrade() {
return this.lastUpgrade;
}
/**
* "module_name": "ind"
*/
@JsonProperty("module_name")
public String getModuleName() {
return this.moduleName;
}
@JsonProperty("modules")
public List<Module> getModules() {
return this.modules;
}
/**
* <pre>
* "place": {
* "altitude": 30.478512648583,
* "city": "Saint-Denis",
* "country": "FR",
* "improveLocProposed": true,
* "location": [
* 2.384033203125,
* 48.936934954094
* ],
* "timezone": "Europe/Paris"
* }
* </pre>
*/
@JsonProperty("place")
public Place getPlace() {
return this.place;
}
/**
* "station_name": "Station"
*/
@JsonProperty("station_name")
public String getStationName() {
return this.stationName;
}
/**
* "type": "NAMain"
*/
@JsonProperty("type")
public String getType() {
return this.type;
}
/**
* "wifi_status"
*/
@JsonProperty("wifi_status")
public Integer getWifiStatus() {
return this.wifiStatus;
}
/**
* "data_type": [
* "Temperature",
* "CO2",
* "Humidity",
* "Noise",
* "Pressure"
* ]
*/
@JsonProperty("data_type")
public List<String> getMeasurements() {
return this.measurements;
}
@Override
public String toString() {
final ToStringBuilder builder = createToStringBuilder();
builder.appendSuper(super.toString());
builder.append("id", this.id);
builder.append("co2Calibrating", this.co2Calibrating);
builder.append("firmware", this.firmware);
builder.append("lastStatusStore", this.lastStatusStore);
builder.append("lastUpgrade", this.lastUpgrade);
builder.append("moduleName", this.moduleName);
builder.append("modules", this.modules);
builder.append("place", this.place);
builder.append("stationName", this.stationName);
builder.append("type", this.type);
builder.append("wifiStatus", this.wifiStatus);
builder.append("measurements", this.measurements);
return builder.toString();
}
public int getWifiLevel() {
int level = this.wifiStatus.intValue();
int result;
if (level <= WIFI_STATUS_GOOD_SIGNAL) {
result = 4;
} else if (level <= WIFI_STATUS_MIDDLE_QUALITY_SIGNAL) {
result = 3;
} else if (level <= WIFI_STATUS_BAD_SIGNAL) {
result = 2;
} else {
result = 1;
}
return result;
}
public Double getAltitude() {
return this.place.altitude;
}
public Double getLatitude() {
return this.place.location.get(1);
}
public Double getLongitude() {
return this.place.location.get(0);
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Module extends AbstractMessagePart {
private String id;
private String moduleName;
private String type;
private Integer firmware;
private Date lastMessage;
private Date lastSeen;
private Integer rfStatus;
private Integer batteryVp;
private List<String> measurements;
/**
* "_id": "02:00:00:00:00:14"
*/
@JsonProperty("_id")
public String getId() {
return this.id;
}
/**
* "module_name": "out"
*/
@JsonProperty("module_name")
public String getModuleName() {
return this.moduleName;
}
/**
* "type": "NAModule1"
*/
@JsonProperty("type")
public String getType() {
return this.type;
}
/**
* "firmware": 91
*/
@JsonProperty("firmware")
public Integer getFirmware() {
return this.firmware;
}
/**
* "last_message": 1441872001
*/
@JsonProperty("last_message")
public Date getLastMessage() {
return this.lastMessage;
}
/**
* "last_seen": 1441868401
*/
@JsonProperty("last_seen")
public Date getLastSeen() {
return this.lastSeen;
}
/**
* "rf_status": 143
*/
@JsonProperty("rf_status")
public Integer getRfStatus() {
return this.rfStatus;
}
/**
* "battery_vp": 31188
*/
@JsonProperty("battery_vp")
public Integer getBatteryVp() {
return this.batteryVp;
}
/**
* "data_type": [
* "Temperature",
* "CO2",
* "Humidity",
* "Noise",
* "Pressure"
* ]
*/
@JsonProperty("data_type")
public List<String> getMeasurements() {
return this.measurements;
}
public int getRfLevel() {
int level = this.rfStatus.intValue();
int result;
if (level < RF_STATUS_FULL_SIGNAL) {
result = 5;
} else if (level < RF_STATUS_HIGH_SIGNAL) {
result = 4;
} else if (level < RF_STATUS_MEDIUM_SIGNAL) {
result = 3;
} else if (level < RF_STATUS_LOW_SIGNAL) {
result = 2;
} else {
result = 1;
}
return result;
}
public int getBatteryLevel() {
int full;
int high;
int medium;
int low;
if (this.type.equalsIgnoreCase(TYPE_MODULE_1)) {
full = BATTERY_MODULE_1_FULL;
high = BATTERY_MODULE_1_HIGH;
medium = BATTERY_MODULE_1_MEDIUM;
low = BATTERY_MODULE_1_LOW;
} else if (this.type.equalsIgnoreCase(TYPE_MODULE_2)) {
full = BATTERY_MODULE_2_FULL;
high = BATTERY_MODULE_2_HIGH;
medium = BATTERY_MODULE_2_MEDIUM;
low = BATTERY_MODULE_2_LOW;
} else if (this.type.equalsIgnoreCase(TYPE_MODULE_3)) {
full = BATTERY_MODULE_3_FULL;
high = BATTERY_MODULE_3_HIGH;
medium = BATTERY_MODULE_3_MEDIUM;
low = BATTERY_MODULE_3_LOW;
} else {
full = BATTERY_MODULE_4_FULL;
high = BATTERY_MODULE_4_HIGH;
medium = BATTERY_MODULE_4_MEDIUM;
low = BATTERY_MODULE_4_LOW;
}
int batteryVp = this.batteryVp;
int result;
if (batteryVp > full) {
result = 5;
} else if (batteryVp > high) {
result = 4;
} else if (batteryVp > medium) {
result = 3;
} else if (batteryVp > low) {
result = 2;
} else { /* very low */
result = 1;
}
return result;
}
public int getBatteryPercentage() {
int max;
int min;
if (this.type.equalsIgnoreCase(TYPE_MODULE_1)) {
max = BATTERY_MODULE_1_RANGE_MAX;
min = BATTERY_MODULE_1_RANGE_MIN;
} else if (this.type.equalsIgnoreCase(TYPE_MODULE_2)) {
max = BATTERY_MODULE_2_RANGE_MAX;
min = BATTERY_MODULE_2_RANGE_MIN;
} else if (this.type.equalsIgnoreCase(TYPE_MODULE_3)) {
max = BATTERY_MODULE_3_RANGE_MAX;
min = BATTERY_MODULE_3_RANGE_MIN;
} else {
max = BATTERY_MODULE_4_RANGE_MAX;
min = BATTERY_MODULE_4_RANGE_MIN;
}
int percent;
int batteryVp = this.batteryVp;
if (batteryVp >= max) {
percent = 100;
} else if (batteryVp <= min) {
percent = 0;
} else {
percent = (int) Math.round(((batteryVp - min) * 100.0) / (max - min));
}
return percent;
}
@Override
public String toString() {
final ToStringBuilder builder = createToStringBuilder();
builder.appendSuper(super.toString());
builder.append("id", this.id);
builder.append("moduleName", this.moduleName);
builder.append("type", this.type);
builder.append("firmware", this.firmware);
builder.append("lastMessage", this.lastMessage);
builder.append("lastSeen", this.lastSeen);
builder.append("rfStatus", this.rfStatus);
builder.append("batteryVp", this.batteryVp);
builder.append("dataTypes", this.measurements);
return builder.toString();
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Place extends AbstractMessagePart {
private Double altitude;
private String city;
private String country;
private Boolean improveLocProposed;
private List<Double> location;
private String timezone;
/**
* "altitude": 30.478512648583
*/
@JsonProperty("altitude")
public Double getAltitude() {
return this.altitude;
}
/**
* "city": "Saint-Denis"
*/
@JsonProperty("city")
public String getCity() {
return this.city;
}
/**
* "country": "FR"
*/
@JsonProperty("country")
public String getCountry() {
return this.country;
}
/**
* "improveLocProposed": true
*/
@JsonProperty("improveLocProposed")
public Boolean isImproveLocProposed() {
return this.improveLocProposed;
}
/**
* <pre>
* "location": [
* 2.384033203125,
* 48.936934954094
* ]
* </pre>
*/
@JsonProperty("location")
public List<Double> getlocation() {
return this.location;
}
/**
* "timezone": "Europe/Paris"
*/
@JsonProperty("timezone")
public String getTimezone() {
return this.timezone;
}
@Override
public String toString() {
final ToStringBuilder builder = createToStringBuilder();
builder.appendSuper(super.toString());
builder.append("altitude", this.altitude);
builder.append("city", this.city);
builder.append("country", this.country);
builder.append("improveLocProposed", this.improveLocProposed);
builder.append("location", this.location);
builder.append("timezone", this.timezone);
return builder.toString();
}
}
private String status;
private Body body;
private Double executionTime;
@JsonProperty("body")
public Body getBody() {
return this.body;
}
public List<Device> getDevices() {
return this.body.devices;
}
/**
* "time_exec": 0.019799947738647
*/
@JsonProperty("time_exec")
public Double getExecutionTime() {
return this.executionTime;
}
@JsonProperty("status")
public String getStatus() {
return this.status;
}
@Override
public String toString() {
final ToStringBuilder builder = createToStringBuilder();
builder.appendSuper(super.toString());
builder.append("status", this.status);
builder.append("body", this.body);
builder.append("executionTime", this.executionTime);
return builder.toString();
}
}