[electroluxair] Updated to changed API (#15265)

Signed-off-by: Jan Gustafsson <jannegpriv@gmail.com>
This commit is contained in:
Jan Gustafsson 2023-07-22 16:26:03 +02:00 committed by GitHub
parent 2129300fd2
commit 2982cc8911
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 353 additions and 527 deletions

View File

@ -2,8 +2,6 @@
This is an openHAB binding for the Pure A9 Air Purifier, by Electrolux. This is an openHAB binding for the Pure A9 Air Purifier, by Electrolux.
This binding uses the Electrolux Delta REST API.
![Electrolux Pure A9](doc/electrolux_pure_a9.png) ![Electrolux Pure A9](doc/electrolux_pure_a9.png)
## Supported Things ## Supported Things
@ -26,15 +24,15 @@ Only the bridge require manual configuration. The Electrolux Pure A9 thing can b
| Parameter | Description | Type | Default | Required | | Parameter | Description | Type | Default | Required |
|-----------|--------------------------------------------------------------|--------|----------|----------| |-----------|--------------------------------------------------------------|--------|----------|----------|
| username | The username used to connect to the Electrolux Wellbeing app | String | NA | yes | | username | The username used to connect to the Electrolux app | String | NA | yes |
| password | The password used to connect to the Electrolux Wellbeing app | String | NA | yes | | password | The password used to connect to the Electrolux app | String | NA | yes |
| refresh | Specifies the refresh interval in second | Number | 600 | yes | | refresh | Specifies the refresh interval in second | Number | 600 | yes |
#### Electrolux Pure A9 #### Electrolux Pure A9
| Parameter | Description | Type | Default | Required | | Parameter | Description | Type | Default | Required |
|-----------|-------------------------------------------------------------------------|--------|----------|----------| |-----------|-------------------------------------------------------------------------|--------|----------|----------|
| deviceId | Product ID of your Electrolux Pure A9 found in Electrolux Wellbeing app | Number | NA | yes | | deviceId | Product ID of your Electrolux Pure A9 found in Electrolux app | Number | NA | yes |
## Channels ## Channels
@ -53,9 +51,10 @@ The following channels are supported:
| co2 | Number:Dimensionless | This channel reports the CO2 level in ppm. | | co2 | Number:Dimensionless | This channel reports the CO2 level in ppm. |
| fanSpeed | Number | This channel sets and reports the current fan speed (1-9). | | fanSpeed | Number | This channel sets and reports the current fan speed (1-9). |
| filterLife | Number:Dimensionless | This channel reports the remaining filter life in %. | | filterLife | Number:Dimensionless | This channel reports the remaining filter life in %. |
| ionizer | Switch | This channel sets and reports the status of the ionizer function (On/Off). | | ionizer | Switch | This channel sets and reports the status of the Ionizer function (On/Off). |
| doorOpen | Contact | This channel reports the status of door (Opened/Closed). | | doorOpen | Contact | This channel reports the status of door (Opened/Closed). |
| workMode | String | This channel sets and reports the current work mode (Auto, Manual, PowerOff.)| | workMode | String | This channel sets and reports the current work mode (Auto, Manual, PowerOff). |
## Full Example ## Full Example
@ -83,4 +82,7 @@ Contact ElectroluxAirDoor "Electrolux Air Door Status" {channel="electroluxair:e
String ElectroluxAirWorkModeSetting "ElectroluxAir Work Mode Setting" {channel="electroluxair:electroluxpurea9:myAPI:myElectroluxPureA9:workMode"} String ElectroluxAirWorkModeSetting "ElectroluxAir Work Mode Setting" {channel="electroluxair:electroluxpurea9:myAPI:myElectroluxPureA9:workMode"}
// Fan speed // Fan speed
Number ElectroluxAirFanSpeed "Electrolux Air Fan Speed Setting" {channel="electroluxair:electroluxpurea9:myAPI:myElectroluxPureA9:fanSpeed"} Number ElectroluxAirFanSpeed "Electrolux Air Fan Speed Setting" {channel="electroluxair:electroluxpurea9:myAPI:myElectroluxPureA9:fanSpeed"}
// Ionizer
Switch ElectroluxAirIonizer "Electrolux Air Ionizer Setting" {channel="electroluxair:electroluxpurea9:myAPI:myElectroluxPureA9:ionizer"}
``` ```

View File

@ -1,4 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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> <modelVersion>4.0.0</modelVersion>

View File

@ -12,6 +12,7 @@
*/ */
package org.openhab.binding.electroluxair.internal.api; package org.openhab.binding.electroluxair.internal.api;
import java.time.Instant;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -27,17 +28,13 @@ import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.electroluxair.internal.ElectroluxAirBridgeConfiguration; import org.openhab.binding.electroluxair.internal.ElectroluxAirBridgeConfiguration;
import org.openhab.binding.electroluxair.internal.ElectroluxAirException; import org.openhab.binding.electroluxair.internal.ElectroluxAirException;
import org.openhab.binding.electroluxair.internal.dto.ElectroluxPureA9DTO; import org.openhab.binding.electroluxair.internal.dto.ElectroluxPureA9DTO;
import org.openhab.binding.electroluxair.internal.dto.ElectroluxPureA9DTO.AppliancesInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import com.google.gson.annotations.SerializedName;
/** /**
* The {@link ElectroluxDeltaAPI} class defines the Elextrolux Delta API * The {@link ElectroluxDeltaAPI} class defines the Elextrolux Delta API
@ -46,10 +43,17 @@ import com.google.gson.annotations.SerializedName;
*/ */
@NonNullByDefault @NonNullByDefault
public class ElectroluxDeltaAPI { public class ElectroluxDeltaAPI {
private static final String CLIENT_URL = "https://electrolux-wellbeing-client.vercel.app/api/mu52m5PR9X"; private static final String CLIENT_ID = "ElxOneApp";
private static final String SERVICE_URL = "https://api.delta.electrolux.com/api/"; private static final String CLIENT_SECRET = "8UKrsKD7jH9zvTV7rz5HeCLkit67Mmj68FvRVTlYygwJYy4dW6KF2cVLPKeWzUQUd6KJMtTifFf4NkDnjI7ZLdfnwcPtTSNtYvbP7OzEkmQD9IjhMOf5e1zeAQYtt2yN";
private static final String X_API_KEY = "2AMqwEV5MqVhTKrRCyYfVF8gmKrd2rAmp7cUsfky";
private static final String BASE_URL = "https://api.ocp.electrolux.one";
private static final String TOKEN_URL = BASE_URL + "/one-account-authorization/api/v1/token";
private static final String AUTHENTICATION_URL = BASE_URL + "/one-account-authentication/api/v1/authenticate";
private static final String API_URL = BASE_URL + "/appliance/api/v2";
private static final String APPLIANCES_URL = API_URL + "/appliances";
private static final String JSON_CONTENT_TYPE = "application/json"; private static final String JSON_CONTENT_TYPE = "application/json";
private static final String LOGIN = "Users/Login";
private static final int MAX_RETRIES = 3; private static final int MAX_RETRIES = 3;
private final Logger logger = LoggerFactory.getLogger(ElectroluxDeltaAPI.class); private final Logger logger = LoggerFactory.getLogger(ElectroluxDeltaAPI.class);
@ -57,6 +61,7 @@ public class ElectroluxDeltaAPI {
private final HttpClient httpClient; private final HttpClient httpClient;
private final ElectroluxAirBridgeConfiguration configuration; private final ElectroluxAirBridgeConfiguration configuration;
private String authToken = ""; private String authToken = "";
private Instant tokenExpiry = Instant.MIN;
public ElectroluxDeltaAPI(ElectroluxAirBridgeConfiguration configuration, Gson gson, HttpClient httpClient) { public ElectroluxDeltaAPI(ElectroluxAirBridgeConfiguration configuration, Gson gson, HttpClient httpClient) {
this.gson = gson; this.gson = gson;
@ -66,70 +71,73 @@ public class ElectroluxDeltaAPI {
public boolean refresh(Map<String, ElectroluxPureA9DTO> electroluxAirThings) { public boolean refresh(Map<String, ElectroluxPureA9DTO> electroluxAirThings) {
try { try {
// Login if (Instant.now().isAfter(this.tokenExpiry)) {
login(); // Login again since token is expired
login();
}
// Get all appliances // Get all appliances
String json = getAppliances(); String json = getAppliances();
JsonArray jsonArray = JsonParser.parseString(json).getAsJsonArray(); ElectroluxPureA9DTO[] dtos = gson.fromJson(json, ElectroluxPureA9DTO[].class);
if (dtos != null) {
for (JsonElement jsonElement : jsonArray) { for (ElectroluxPureA9DTO dto : dtos) {
String pncId = jsonElement.getAsJsonObject().get("pncId").getAsString(); String applianceId = dto.getApplianceId();
// Get appliance info
// Get appliance info String jsonApplianceInfo = getAppliancesInfo(applianceId);
String jsonApplianceInfo = getAppliancesInfo(pncId); ElectroluxPureA9DTO.ApplianceInfo applianceInfo = gson.fromJson(jsonApplianceInfo,
AppliancesInfo appliancesInfo = gson.fromJson(jsonApplianceInfo, AppliancesInfo.class); ElectroluxPureA9DTO.ApplianceInfo.class);
if (applianceInfo != null) {
// Get applicance data if ("AIR_PURIFIER".equals(applianceInfo.getDeviceType())) {
ElectroluxPureA9DTO dto = getAppliancesData(pncId, ElectroluxPureA9DTO.class); dto.setApplianceInfo(applianceInfo);
if (appliancesInfo != null) { electroluxAirThings.put(dto.getProperties().getReported().getDeviceId(), dto);
dto.setApplicancesInfo(appliancesInfo); }
}
} }
electroluxAirThings.put(dto.getTwin().getProperties().getReported().deviceId, dto); return true;
} }
return true; } catch (JsonSyntaxException | ElectroluxAirException e) {
} catch (ElectroluxAirException e) {
logger.warn("Failed to refresh! {}", e.getMessage()); logger.warn("Failed to refresh! {}", e.getMessage());
} }
return false; return false;
} }
public boolean workModePowerOff(String pncId) { public boolean workModePowerOff(String applianceId) {
String commandJSON = "{ \"WorkMode\": \"PowerOff\" }"; String commandJSON = "{ \"WorkMode\": \"PowerOff\" }";
try { try {
return sendCommand(commandJSON, pncId); return sendCommand(commandJSON, applianceId);
} catch (ElectroluxAirException e) { } catch (ElectroluxAirException e) {
logger.warn("Work mode powerOff failed {}", e.getMessage()); logger.warn("Work mode powerOff failed {}", e.getMessage());
} }
return false; return false;
} }
public boolean workModeAuto(String pncId) { public boolean workModeAuto(String applianceId) {
String commandJSON = "{ \"WorkMode\": \"Auto\" }"; String commandJSON = "{ \"WorkMode\": \"Auto\" }";
try { try {
return sendCommand(commandJSON, pncId); return sendCommand(commandJSON, applianceId);
} catch (ElectroluxAirException e) { } catch (ElectroluxAirException e) {
logger.warn("Work mode auto failed {}", e.getMessage()); logger.warn("Work mode auto failed {}", e.getMessage());
} }
return false; return false;
} }
public boolean workModeManual(String pncId) { public boolean workModeManual(String applianceId) {
String commandJSON = "{ \"WorkMode\": \"Manual\" }"; String commandJSON = "{ \"WorkMode\": \"Manual\" }";
try { try {
return sendCommand(commandJSON, pncId); return sendCommand(commandJSON, applianceId);
} catch (ElectroluxAirException e) { } catch (ElectroluxAirException e) {
logger.warn("Work mode manual failed {}", e.getMessage()); logger.warn("Work mode manual failed {}", e.getMessage());
} }
return false; return false;
} }
public boolean setFanSpeedLevel(String pncId, int fanSpeedLevel) { public boolean setFanSpeedLevel(String applianceId, int fanSpeedLevel) {
if (fanSpeedLevel < 1 && fanSpeedLevel > 10) { if (fanSpeedLevel < 1 && fanSpeedLevel > 10) {
return false; return false;
} else { } else {
String commandJSON = "{ \"Fanspeed\": " + fanSpeedLevel + "}"; String commandJSON = "{ \"Fanspeed\": " + fanSpeedLevel + "}";
try { try {
return sendCommand(commandJSON, pncId); return sendCommand(commandJSON, applianceId);
} catch (ElectroluxAirException e) { } catch (ElectroluxAirException e) {
logger.warn("Work mode manual failed {}", e.getMessage()); logger.warn("Work mode manual failed {}", e.getMessage());
} }
@ -137,40 +145,54 @@ public class ElectroluxDeltaAPI {
return false; return false;
} }
public boolean setIonizer(String pncId, String ionizerStatus) { public boolean setIonizer(String applianceId, String ionizerStatus) {
String commandJSON = "{ \"Ionizer\": " + ionizerStatus + "}"; String commandJSON = "{ \"Ionizer\": " + ionizerStatus + "}";
try { try {
return sendCommand(commandJSON, pncId); return sendCommand(commandJSON, applianceId);
} catch (ElectroluxAirException e) { } catch (ElectroluxAirException e) {
logger.warn("Work mode manual failed {}", e.getMessage()); logger.warn("Work mode manual failed {}", e.getMessage());
} }
return false; return false;
} }
private void login() throws ElectroluxAirException { private Request createRequest(String uri, HttpMethod httpMethod) {
// Fetch ClientToken Request request = httpClient.newRequest(uri).method(httpMethod);
Request request = httpClient.newRequest(CLIENT_URL).method(HttpMethod.GET);
request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE); request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
logger.debug("HTTP GET Request {}.", request.toString()); logger.debug("HTTP POST Request {}.", request.toString());
return request;
}
private void login() throws ElectroluxAirException {
try { try {
String json = "{\"clientId\": \"" + CLIENT_ID + "\", \"clientSecret\": \"" + CLIENT_SECRET
+ "\", \"grantType\": \"client_credentials\"}";
// Fetch ClientToken
Request request = createRequest(TOKEN_URL, HttpMethod.POST);
request.content(new StringContentProvider(json), JSON_CONTENT_TYPE);
logger.debug("HTTP POST Request {}.", request.toString());
ContentResponse httpResponse = request.send(); ContentResponse httpResponse = request.send();
if (httpResponse.getStatus() != HttpStatus.OK_200) { if (httpResponse.getStatus() != HttpStatus.OK_200) {
throw new ElectroluxAirException("Failed to login " + httpResponse.getContentAsString()); throw new ElectroluxAirException("Failed to get token 1" + httpResponse.getContentAsString());
} }
String json = httpResponse.getContentAsString(); json = httpResponse.getContentAsString();
logger.trace("Token 1: {}", json);
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
String clientToken = jsonObject.get("accessToken").getAsString(); String clientToken = jsonObject.get("accessToken").getAsString();
// Login using ClientToken // Login using access token 1
json = "{ \"Username\": \"" + configuration.username + "\", \"Password\": \"" + configuration.password json = "{ \"username\": \"" + configuration.username + "\", \"password\": \"" + configuration.password
+ "\" }"; + "\" }";
request = httpClient.newRequest(SERVICE_URL + LOGIN).method(HttpMethod.POST); request = createRequest(AUTHENTICATION_URL, HttpMethod.POST);
request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
request.header(HttpHeader.AUTHORIZATION, "Bearer " + clientToken); request.header(HttpHeader.AUTHORIZATION, "Bearer " + clientToken);
request.header("x-api-key", X_API_KEY);
request.content(new StringContentProvider(json), JSON_CONTENT_TYPE); request.content(new StringContentProvider(json), JSON_CONTENT_TYPE);
logger.debug("HTTP POST Request {}.", request.toString()); logger.debug("HTTP POST Request {}.", request.toString());
@ -179,10 +201,33 @@ public class ElectroluxDeltaAPI {
if (httpResponse.getStatus() != HttpStatus.OK_200) { if (httpResponse.getStatus() != HttpStatus.OK_200) {
throw new ElectroluxAirException("Failed to login " + httpResponse.getContentAsString()); throw new ElectroluxAirException("Failed to login " + httpResponse.getContentAsString());
} }
json = httpResponse.getContentAsString();
logger.trace("Token 2: {}", json);
jsonObject = JsonParser.parseString(json).getAsJsonObject();
String idToken = jsonObject.get("idToken").getAsString();
String countryCode = jsonObject.get("countryCode").getAsString();
String credentials = "{\"clientId\": \"" + CLIENT_ID + "\", \"idToken\": \"" + idToken
+ "\", \"grantType\": \"urn:ietf:params:oauth:grant-type:token-exchange\"}";
// Fetch access token 2
request = createRequest(TOKEN_URL, HttpMethod.POST);
request.header("Origin-Country-Code", countryCode);
request.content(new StringContentProvider(credentials), JSON_CONTENT_TYPE);
logger.debug("HTTP POST Request {}.", request.toString());
httpResponse = request.send();
if (httpResponse.getStatus() != HttpStatus.OK_200) {
throw new ElectroluxAirException("Failed to get token 1" + httpResponse.getContentAsString());
}
// Fetch AccessToken // Fetch AccessToken
json = httpResponse.getContentAsString(); json = httpResponse.getContentAsString();
logger.trace("AccessToken: {}", json);
jsonObject = JsonParser.parseString(json).getAsJsonObject(); jsonObject = JsonParser.parseString(json).getAsJsonObject();
this.authToken = jsonObject.get("accessToken").getAsString(); this.authToken = jsonObject.get("accessToken").getAsString();
int expiresIn = jsonObject.get("expiresIn").getAsInt();
this.tokenExpiry = Instant.now().plusSeconds(expiresIn);
} catch (InterruptedException | TimeoutException | ExecutionException e) { } catch (InterruptedException | TimeoutException | ExecutionException e) {
throw new ElectroluxAirException(e); throw new ElectroluxAirException(e);
} }
@ -192,10 +237,9 @@ public class ElectroluxDeltaAPI {
try { try {
for (int i = 0; i < MAX_RETRIES; i++) { for (int i = 0; i < MAX_RETRIES; i++) {
try { try {
Request request = httpClient.newRequest(SERVICE_URL + uri).method(HttpMethod.GET); Request request = createRequest(uri, HttpMethod.GET);
request.header(HttpHeader.AUTHORIZATION, "Bearer " + authToken); request.header(HttpHeader.AUTHORIZATION, "Bearer " + authToken);
request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE); request.header("x-api-key", X_API_KEY);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
ContentResponse response = request.send(); ContentResponse response = request.send();
String content = response.getContentAsString(); String content = response.getContentAsString();
@ -218,44 +262,28 @@ public class ElectroluxDeltaAPI {
} }
private String getAppliances() throws ElectroluxAirException { private String getAppliances() throws ElectroluxAirException {
String uri = "Domains/Appliances";
try { try {
return getFromApi(uri); return getFromApi(APPLIANCES_URL);
} catch (ElectroluxAirException | InterruptedException e) { } catch (ElectroluxAirException | InterruptedException e) {
throw new ElectroluxAirException(e); throw new ElectroluxAirException(e);
} }
} }
private String getAppliancesInfo(String pncId) throws ElectroluxAirException { private String getAppliancesInfo(String applianceId) throws ElectroluxAirException {
String uri = "AppliancesInfo/" + pncId;
try { try {
return getFromApi(uri); return getFromApi(APPLIANCES_URL + "/" + applianceId + "/info");
} catch (ElectroluxAirException | InterruptedException e) { } catch (ElectroluxAirException | InterruptedException e) {
throw new ElectroluxAirException(e); throw new ElectroluxAirException(e);
} }
} }
private <T> T getAppliancesData(String pncId, Class<T> dto) throws ElectroluxAirException { private boolean sendCommand(String commandJSON, String applianceId) throws ElectroluxAirException {
String uri = "Appliances/" + pncId;
String json;
try {
json = getFromApi(uri);
} catch (ElectroluxAirException | InterruptedException e) {
throw new ElectroluxAirException(e);
}
return gson.fromJson(json, dto);
}
private boolean sendCommand(String commandJSON, String pncId) throws ElectroluxAirException {
String uri = "Appliances/" + pncId + "/Commands";
try { try {
for (int i = 0; i < MAX_RETRIES; i++) { for (int i = 0; i < MAX_RETRIES; i++) {
try { try {
Request request = httpClient.newRequest(SERVICE_URL + uri).method(HttpMethod.PUT); Request request = createRequest(APPLIANCES_URL + "/" + applianceId + "/command", HttpMethod.PUT);
request.header(HttpHeader.AUTHORIZATION, "Bearer " + authToken); request.header(HttpHeader.AUTHORIZATION, "Bearer " + authToken);
request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE); request.header("x-api-key", X_API_KEY);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
request.content(new StringContentProvider(commandJSON), JSON_CONTENT_TYPE); request.content(new StringContentProvider(commandJSON), JSON_CONTENT_TYPE);
ContentResponse response = request.send(); ContentResponse response = request.send();
@ -266,19 +294,7 @@ public class ElectroluxDeltaAPI {
logger.debug("sendCommand failed, HTTP status: {}", response.getStatus()); logger.debug("sendCommand failed, HTTP status: {}", response.getStatus());
login(); login();
} else { } else {
CommandResponseDTO commandResponse = gson.fromJson(content, CommandResponseDTO.class); return true;
if (commandResponse != null) {
if (commandResponse.code == 200000) {
return true;
} else {
logger.warn("Failed to send command, error code: {}, description: {}",
commandResponse.code, commandResponse.codeDescription);
return false;
}
} else {
logger.warn("Failed to send command, commandResponse is null!");
return false;
}
} }
} catch (TimeoutException | InterruptedException e) { } catch (TimeoutException | InterruptedException e) {
logger.warn("TimeoutException error in get"); logger.warn("TimeoutException error in get");
@ -289,26 +305,4 @@ public class ElectroluxDeltaAPI {
} }
return false; return false;
} }
@SuppressWarnings("unused")
private static class CommandResponseDTO {
public int code;
public String codeDescription = "";
public String information = "";
public String message = "";
public PayloadDTO payload = new PayloadDTO();
public int status;
}
private static class PayloadDTO {
@SerializedName("Ok")
public boolean ok;
@SerializedName("Response")
public ResponseDTO response = new ResponseDTO();
}
private static class ResponseDTO {
@SerializedName("Workmode")
public String workmode = "";
}
} }

View File

@ -12,6 +12,9 @@
*/ */
package org.openhab.binding.electroluxair.internal.dto; package org.openhab.binding.electroluxair.internal.dto;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
@ -23,354 +26,232 @@ import com.google.gson.annotations.SerializedName;
*/ */
@NonNullByDefault @NonNullByDefault
public class ElectroluxPureA9DTO { public class ElectroluxPureA9DTO {
public String pncId = ""; private String applianceId = "";
public ApplianceData applianceData = new ApplianceData(); private ApplianceInfo applianceInfo = new ApplianceInfo();
public AppliancesInfo applicancesInfo = new AppliancesInfo(); private ApplianceData applianceData = new ApplianceData();
private Properties properties = new Properties();
private String status = "";
private String connectionState = "";
public Twin twin = new Twin(); public String getApplianceId() {
public String telemetry = ""; return applianceId;
}
public String getPncId() { public ApplianceInfo getApplianceInfo() {
return pncId; return applianceInfo;
}
public void setApplianceInfo(ApplianceInfo applianceInfo) {
this.applianceInfo = applianceInfo;
} }
public ApplianceData getApplianceData() { public ApplianceData getApplianceData() {
return applianceData; return applianceData;
} }
public AppliancesInfo getApplicancesInfo() { public Properties getProperties() {
return applicancesInfo; return properties;
} }
public void setApplicancesInfo(AppliancesInfo applicancesInfo) { public String getStatus() {
this.applicancesInfo = applicancesInfo; return status;
} }
public Twin getTwin() { public String getConnectionState() {
return twin; return connectionState;
} }
public String getTelemetry() { public class ApplianceInfo {
return telemetry; private String manufacturingDateCode = "";
private String serialNumber = "";
private String pnc = "";
private String brand = "";
private String market = "";
private String productArea = "";
private String deviceType = "";
private String project = "";
private String model = "";
private String variant = "";
private String colour = "";
public String getManufacturingDateCode() {
return manufacturingDateCode;
}
public String getSerialNumber() {
return serialNumber;
}
public String getPnc() {
return pnc;
}
public String getBrand() {
return brand;
}
public String getMarket() {
return market;
}
public String getProductArea() {
return productArea;
}
public String getDeviceType() {
return deviceType;
}
public String getProject() {
return project;
}
public String getModel() {
return model;
}
public String getVariant() {
return variant;
}
public String getColour() {
return colour;
}
} }
public class MetaData1 { class ApplianceData {
private String applianceName = "";
private String created = "";
private String modelName = "";
@SerializedName("$lastUpdated") public String getApplianceName() {
public String lastUpdated1 = ""; return applianceName;
@SerializedName("$lastUpdatedVersion") }
public int lastUpdatedVersion1;
@SerializedName("TimeZoneStandardName")
public TimeZoneStandardName timeZoneStandardName = new TimeZoneStandardName();
@SerializedName("FrmVer_NIU")
public FrmVerNIU frmVerNIU = new FrmVerNIU();
}
public class Metadata2 { public String getCreated() {
return created;
}
@SerializedName("$lastUpdated") public String getModelName() {
public String lastUpdated2 = ""; return modelName;
@SerializedName("FrmVer_NIU") }
public FrmVerNIU frmVerNIU = new FrmVerNIU();
@SerializedName("Workmode")
public Workmode workmode = new Workmode();
@SerializedName("FilterRFID")
public FilterRFID filterRFID = new FilterRFID();
@SerializedName("FilterLife")
public FilterLife filterLife = new FilterLife();
@SerializedName("Fanspeed")
public Fanspeed fanspeed = new Fanspeed();
@SerializedName("UILight")
public UILight uILight = new UILight();
@SerializedName("SafetyLock")
public SafetyLock safetyLock = new SafetyLock();
@SerializedName("Ionizer")
public Ionizer ionizer = new Ionizer();
@SerializedName("Sleep")
public Sleep sleep = new Sleep();
@SerializedName("Scheduler")
public Scheduler scheduler = new Scheduler();
@SerializedName("FilterType")
public FilterType filterType = new FilterType();
@SerializedName("DspIcoPM2_5")
public DspIcoPM25 dspIcoPM25 = new DspIcoPM25();
@SerializedName("DspIcoPM1")
public DspIcoPM1 dspIcoPM1 = new DspIcoPM1();
@SerializedName("DspIcoPM10")
public DspIcoPM10 dspIcoPM10 = new DspIcoPM10();
@SerializedName("DspIcoTVOC")
public DspIcoTVOC dspIcoTVOC = new DspIcoTVOC();
@SerializedName("ErrPM2_5")
public ErrPM25 errPM25 = new ErrPM25();
@SerializedName("ErrTVOC")
public ErrTVOC errTVOC = new ErrTVOC();
@SerializedName("ErrTempHumidity")
public ErrTempHumidity errTempHumidity = new ErrTempHumidity();
@SerializedName("ErrFanMtr")
public ErrFanMtr errFanMtr = new ErrFanMtr();
@SerializedName("ErrCommSensorDisplayBrd")
public ErrCommSensorDisplayBrd errCommSensorDisplayBrd = new ErrCommSensorDisplayBrd();
@SerializedName("DoorOpen")
public DoorOpen doorOpen = new DoorOpen();
@SerializedName("ErrRFID")
public ErrRFID errRFID = new ErrRFID();
@SerializedName("SignalStrength")
public SignalStrength signalStrength = new SignalStrength();
@SerializedName("PM1")
public PM1 pM1 = new PM1();
@SerializedName("PM2_5")
public PM25 pM25 = new PM25();
@SerializedName("PM10")
public PM10 pM10 = new PM10();
@SerializedName("TVOC")
public TVOC tVOC = new TVOC();
@SerializedName("CO2")
public CO2 cO2 = new CO2();
@SerializedName("Temp")
public Temp temp = new Temp();
@SerializedName("Humidity")
public Humidity humidity = new Humidity();
@SerializedName("EnvLightLvl")
public EnvLightLvl envLightLvl = new EnvLightLvl();
@SerializedName("RSSI")
public RSSI rSSI = new RSSI();
}
public class ApplianceData {
public String applianceName = "";
public String created = "";
public String modelName = "";
public String pncId = "";
}
public class AppliancesInfo {
public String brand = "";
public String colour = "";
public String device = "";
public String model = "";
public String serialNumber = "";
}
public class CO2 {
@SerializedName("$lastUpdated")
public String lastUpdated3 = "";
}
public class Desired {
@SerializedName("TimeZoneStandardName")
public String timeZoneStandardName = "";
@SerializedName("FrmVer_NIU")
public String frmVerNIU = "";
@SerializedName("$metadata")
public MetaData1 metadata3 = new MetaData1();
@SerializedName("$version")
public int version;
}
public class DoorOpen {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class DspIcoPM1 {
@SerializedName("lastUpdated")
public String lastUpdated = "";
}
public class DspIcoPM10 {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class DspIcoPM25 {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class DspIcoTVOC {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class EnvLightLvl {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class ErrCommSensorDisplayBrd {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class ErrFanMtr {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class ErrPM25 {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class ErrRFID {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class ErrTVOC {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class ErrTempHumidity {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class Fanspeed {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class FilterLife {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class FilterRFID {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class FilterType {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class FrmVerNIU {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
@SerializedName("$lastUpdatedVersion")
public int lastUpdatedVersion;
}
// public class FrmVerNIU_ {
// @SerializedName("$lastUpdated")
// public String lastUpdated = "";
// }
public class Humidity {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class Ionizer {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class PM1 {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class PM10 {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class PM25 {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
} }
public class Properties { public class Properties {
public Desired desired = new Desired(); private Desired desired = new Desired();
public Reported reported = new Reported(); private Reported reported = new Reported();
private Object metadata = new Object();
public Desired getDesired() {
return desired;
}
public Reported getReported() { public Reported getReported() {
return reported; return reported;
} }
public Object getMetadata() {
return metadata;
}
} }
public class RSSI { class Desired {
@SerializedName("$lastUpdated") @SerializedName("TimeZoneStandardName")
public String lastUpdated = ""; private String timeZoneStandardName = "";
@SerializedName("FrmVer_NIU")
private String frmVerNIU = "";
@SerializedName("LocationReq")
private boolean locationReq;
private Map<String, Object> metadata = new HashMap<>();
private int version;
public String getTimeZoneStandardName() {
return timeZoneStandardName;
}
public String getFrmVerNIU() {
return frmVerNIU;
}
public boolean isLocationReq() {
return locationReq;
}
public Map<String, Object> getMetadata() {
return metadata;
}
public int getVersion() {
return version;
}
} }
public class Reported { public class Reported {
@SerializedName("FrmVer_NIU") @SerializedName("FrmVer_NIU")
public String frmVerNIU = ""; private String frmVerNIU = "";
@SerializedName("Workmode") @SerializedName("Workmode")
public String workmode = ""; private String workmode = "";
@SerializedName("FilterRFID") @SerializedName("FilterRFID")
public String filterRFID = ""; private String filterRFID = "";
@SerializedName("FilterLife") @SerializedName("FilterLife")
public int filterLife; private int filterLife = 0;
@SerializedName("Fanspeed") @SerializedName("Fanspeed")
public int fanspeed; private int fanSpeed = 0;
@SerializedName("UILight") @SerializedName("UILight")
public boolean uILight; private boolean uiLight = false;
@SerializedName("SafetyLock") @SerializedName("SafetyLock")
public boolean safetyLock; private boolean safetyLock = false;
@SerializedName("Ionizer") @SerializedName("Ionizer")
public boolean ionizer; private boolean ionizer = false;
@SerializedName("Sleep") @SerializedName("Sleep")
public boolean sleep; private boolean sleep = false;
@SerializedName("Scheduler") @SerializedName("Scheduler")
public boolean scheduler; private boolean scheduler = false;
@SerializedName("FilterType") @SerializedName("FilterType")
public int filterType; private int filterType = 0;
@SerializedName("DspIcoPM2_5") @SerializedName("DspIcoPM2_5")
public boolean dspIcoPM25; private boolean dspIcoPM25 = false;
@SerializedName("DspIcoPM1") @SerializedName("DspIcoPM1")
public boolean dspIcoPM1; private boolean dspIcoPM1 = false;
@SerializedName("DspIcoPM10") @SerializedName("DspIcoPM10")
public boolean dspIcoPM10; private boolean dspIcoPM10 = false;
@SerializedName("DspIcoTVOC") @SerializedName("DspIcoTVOC")
public boolean dspIcoTVOC; private boolean dspIcoTVOC = false;
@SerializedName("ErrPM2_5") @SerializedName("ErrPM2_5")
public boolean errPM25; private boolean errPM25 = false;
@SerializedName("ErrTVOC") @SerializedName("ErrTVOC")
public boolean errTVOC; private boolean errTVOC = false;
@SerializedName("ErrTempHumidity") @SerializedName("ErrTempHumidity")
public boolean errTempHumidity; private boolean errTempHumidity = false;
@SerializedName("ErrFanMtr") @SerializedName("ErrFanMtr")
public boolean errFanMtr; private boolean errFanMtr = false;
@SerializedName("ErrCommSensorDisplayBrd") @SerializedName("ErrCommSensorDisplayBrd")
public boolean errCommSensorDisplayBrd; private boolean errCommSensorDisplayBrd = false;
@SerializedName("DoorOpen") @SerializedName("DoorOpen")
public boolean doorOpen; private boolean doorOpen = false;
@SerializedName("ErrRFID") @SerializedName("ErrRFID")
public boolean errRFID; private boolean errRFID = false;
@SerializedName("SignalStrength") @SerializedName("SignalStrength")
public String signalStrength = ""; private String signalStrength = "";
@SerializedName("$metadata") private Map<String, Object> metadata = new HashMap<>();
public Metadata2 metadata2 = new Metadata2(); private int version = 0;
@SerializedName("$version") private String deviceId = "";
public int version;
public String deviceId = "";
@SerializedName("PM1")
public int pM1;
@SerializedName("PM2_5")
public int pM25;
@SerializedName("PM10")
public int pM10;
@SerializedName("TVOC")
public int tVOC;
@SerializedName("CO2") @SerializedName("CO2")
public int cO2; private int co2 = 0;
@SerializedName("TVOC")
private int tvoc = 0;
@SerializedName("Temp") @SerializedName("Temp")
public int temp; private int temp = 0;
@SerializedName("Humidity") @SerializedName("Humidity")
public int humidity; private int humidity = 0;
@SerializedName("EnvLightLvl")
public int envLightLvl;
@SerializedName("RSSI") @SerializedName("RSSI")
public int rSSI; private int rssi = 0;
@SerializedName("PM1")
private int pm1 = 0;
@SerializedName("PM2_5")
private int pm25 = 0;
@SerializedName("PM10")
private int pm10 = 0;
public String getFrmVerNIU() { public String getFrmVerNIU() {
return frmVerNIU; return frmVerNIU;
@ -389,11 +270,11 @@ public class ElectroluxPureA9DTO {
} }
public int getFanspeed() { public int getFanspeed() {
return fanspeed; return fanSpeed;
} }
public boolean isuILight() { public boolean isUILight() {
return uILight; return uiLight;
} }
public boolean isSafetyLock() { public boolean isSafetyLock() {
@ -464,6 +345,10 @@ public class ElectroluxPureA9DTO {
return signalStrength; return signalStrength;
} }
public Map<String, Object> getMetadata() {
return metadata;
}
public int getVersion() { public int getVersion() {
return version; return version;
} }
@ -472,24 +357,12 @@ public class ElectroluxPureA9DTO {
return deviceId; return deviceId;
} }
public int getpM1() { public int getCO2() {
return pM1; return co2;
} }
public int getpM25() { public int getTVOC() {
return pM25; return tvoc;
}
public int getpM10() {
return pM10;
}
public int gettVOC() {
return tVOC;
}
public int getcO2() {
return cO2;
} }
public int getTemp() { public int getTemp() {
@ -500,82 +373,20 @@ public class ElectroluxPureA9DTO {
return humidity; return humidity;
} }
public int getEnvLightLvl() { public int getRSSI() {
return envLightLvl; return rssi;
} }
public int getrSSI() { public int getPM1() {
return rSSI; return pm1;
}
}
public class SafetyLock {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class Scheduler {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class SignalStrength {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class Sleep {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class TVOC {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class Temp {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class TimeZoneStandardName {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
@SerializedName("$lastUpdatedVersion")
public int lastUpdatedVersion;
}
public class Twin {
public String deviceId = "";
public Properties properties = new Properties();
public String status = "";
public String connectionState = "";
public String getDeviceId() {
return deviceId;
} }
public Properties getProperties() { public int getPM25() {
return properties; return pm25;
} }
public String getStatus() { public int getPM10() {
return status; return pm10;
} }
public String getConnectionState() {
return connectionState;
}
}
public class UILight {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
}
public class Workmode {
@SerializedName("$lastUpdated")
public String lastUpdated = "";
} }
} }

View File

@ -12,7 +12,7 @@
*/ */
package org.openhab.binding.electroluxair.internal.handler; package org.openhab.binding.electroluxair.internal.handler;
import static org.openhab.binding.electroluxair.internal.ElectroluxAirBindingConstants.THING_TYPE_BRIDGE; import static org.openhab.binding.electroluxair.internal.ElectroluxAirBindingConstants.*;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -37,6 +37,7 @@ import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseBridgeHandler; import org.openhab.core.thing.binding.BaseBridgeHandler;
import org.openhab.core.thing.binding.ThingHandlerService; import org.openhab.core.thing.binding.ThingHandlerService;
import org.openhab.core.types.Command; import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -147,6 +148,8 @@ public class ElectroluxAirBridgeHandler extends BaseBridgeHandler {
@Override @Override
public void handleCommand(ChannelUID channelUID, Command command) { public void handleCommand(ChannelUID channelUID, Command command) {
return; if (CHANNEL_STATUS.equals(channelUID.getId()) && command instanceof RefreshType) {
scheduler.schedule(this::refreshAndUpdateStatus, 1, TimeUnit.SECONDS);
}
} }
} }

View File

@ -22,6 +22,7 @@ import javax.measure.quantity.Temperature;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.electroluxair.internal.ElectroluxAirBindingConstants;
import org.openhab.binding.electroluxair.internal.ElectroluxAirConfiguration; import org.openhab.binding.electroluxair.internal.ElectroluxAirConfiguration;
import org.openhab.binding.electroluxair.internal.api.ElectroluxDeltaAPI; import org.openhab.binding.electroluxair.internal.api.ElectroluxDeltaAPI;
import org.openhab.binding.electroluxair.internal.dto.ElectroluxPureA9DTO; import org.openhab.binding.electroluxair.internal.dto.ElectroluxPureA9DTO;
@ -38,6 +39,7 @@ 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;
import org.openhab.core.thing.binding.BaseThingHandler; import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.thing.binding.BridgeHandler;
import org.openhab.core.types.Command; import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType; import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State; import org.openhab.core.types.State;
@ -66,30 +68,46 @@ public class ElectroluxAirHandler extends BaseThingHandler {
public void handleCommand(ChannelUID channelUID, Command command) { public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("Command received: {}", command); logger.debug("Command received: {}", command);
if (CHANNEL_STATUS.equals(channelUID.getId()) || command instanceof RefreshType) { if (CHANNEL_STATUS.equals(channelUID.getId()) || command instanceof RefreshType) {
update(); Bridge bridge = getBridge();
if (bridge != null) {
BridgeHandler bridgeHandler = bridge.getHandler();
if (bridgeHandler != null) {
bridgeHandler.handleCommand(channelUID, command);
}
}
} else { } else {
ElectroluxPureA9DTO dto = getElectroluxPureA9DTO(); ElectroluxPureA9DTO dto = getElectroluxPureA9DTO();
ElectroluxDeltaAPI api = getElectroluxDeltaAPO(); ElectroluxDeltaAPI api = getElectroluxDeltaAPI();
if (api != null && dto != null) { if (api != null && dto != null) {
if (CHANNEL_WORK_MODE.equals(channelUID.getId())) { if (CHANNEL_WORK_MODE.equals(channelUID.getId())) {
if (command.toString().equals(COMMAND_WORKMODE_POWEROFF)) { if (command.toString().equals(COMMAND_WORKMODE_POWEROFF)) {
api.workModePowerOff(dto.getPncId()); api.workModePowerOff(dto.getApplianceId());
} else if (command.toString().equals(COMMAND_WORKMODE_AUTO)) { } else if (command.toString().equals(COMMAND_WORKMODE_AUTO)) {
api.workModeAuto(dto.getPncId()); api.workModeAuto(dto.getApplianceId());
} else if (command.toString().equals(COMMAND_WORKMODE_MANUAL)) { } else if (command.toString().equals(COMMAND_WORKMODE_MANUAL)) {
api.workModeManual(dto.getPncId()); api.workModeManual(dto.getApplianceId());
} }
} else if (CHANNEL_FAN_SPEED.equals(channelUID.getId())) { } else if (CHANNEL_FAN_SPEED.equals(channelUID.getId())) {
api.setFanSpeedLevel(dto.getPncId(), Integer.parseInt(command.toString())); api.setFanSpeedLevel(dto.getApplianceId(), Integer.parseInt(command.toString()));
} else if (CHANNEL_IONIZER.equals(channelUID.getId())) { } else if (CHANNEL_IONIZER.equals(channelUID.getId())) {
if (command == OnOffType.OFF) { if (command == OnOffType.OFF) {
api.setIonizer(dto.getPncId(), "false"); api.setIonizer(dto.getApplianceId(), "false");
} else if (command == OnOffType.ON) { } else if (command == OnOffType.ON) {
api.setIonizer(dto.getPncId(), "true"); api.setIonizer(dto.getApplianceId(), "true");
} else { } else {
logger.debug("Unknown command! {}", command); logger.debug("Unknown command! {}", command);
} }
} }
Bridge bridge = getBridge();
if (bridge != null) {
BridgeHandler bridgeHandler = bridge.getHandler();
if (bridgeHandler != null) {
bridgeHandler.handleCommand(
new ChannelUID(this.thing.getUID(), ElectroluxAirBindingConstants.CHANNEL_STATUS),
RefreshType.REFRESH);
}
}
} }
} }
} }
@ -115,7 +133,7 @@ public class ElectroluxAirHandler extends BaseThingHandler {
} }
} }
private @Nullable ElectroluxDeltaAPI getElectroluxDeltaAPO() { private @Nullable ElectroluxDeltaAPI getElectroluxDeltaAPI() {
Bridge bridge = getBridge(); Bridge bridge = getBridge();
if (bridge != null) { if (bridge != null) {
ElectroluxAirBridgeHandler handler = (ElectroluxAirBridgeHandler) bridge.getHandler(); ElectroluxAirBridgeHandler handler = (ElectroluxAirBridgeHandler) bridge.getHandler();
@ -143,6 +161,7 @@ public class ElectroluxAirHandler extends BaseThingHandler {
getThing().getChannels().stream().map(Channel::getUID).filter(channelUID -> isLinked(channelUID)) getThing().getChannels().stream().map(Channel::getUID).filter(channelUID -> isLinked(channelUID))
.forEach(channelUID -> { .forEach(channelUID -> {
State state = getValue(channelUID.getId(), dto); State state = getValue(channelUID.getId(), dto);
logger.trace("Channel: {}, State: {}", channelUID, state);
updateState(channelUID, state); updateState(channelUID, state);
}); });
updateStatus(ThingStatus.ONLINE); updateStatus(ThingStatus.ONLINE);
@ -152,38 +171,35 @@ public class ElectroluxAirHandler extends BaseThingHandler {
private State getValue(String channelId, ElectroluxPureA9DTO dto) { private State getValue(String channelId, ElectroluxPureA9DTO dto) {
switch (channelId) { switch (channelId) {
case CHANNEL_TEMPERATURE: case CHANNEL_TEMPERATURE:
return new QuantityType<Temperature>(dto.getTwin().getProperties().getReported().getTemp(), return new QuantityType<Temperature>(dto.getProperties().getReported().getTemp(), SIUnits.CELSIUS);
SIUnits.CELSIUS);
case CHANNEL_HUMIDITY: case CHANNEL_HUMIDITY:
return new QuantityType<Dimensionless>(dto.getTwin().getProperties().getReported().getHumidity(), return new QuantityType<Dimensionless>(dto.getProperties().getReported().getHumidity(), Units.PERCENT);
Units.PERCENT);
case CHANNEL_TVOC: case CHANNEL_TVOC:
return new QuantityType<Density>(dto.getTwin().getProperties().getReported().gettVOC(), return new QuantityType<Density>(dto.getProperties().getReported().getTVOC(),
Units.MICROGRAM_PER_CUBICMETRE); Units.MICROGRAM_PER_CUBICMETRE);
case CHANNEL_PM1: case CHANNEL_PM1:
return new QuantityType<Dimensionless>(dto.getTwin().getProperties().getReported().getpM1(), return new QuantityType<Dimensionless>(dto.getProperties().getReported().getPM1(),
Units.PARTS_PER_BILLION); Units.PARTS_PER_BILLION);
case CHANNEL_PM25: case CHANNEL_PM25:
return new QuantityType<Dimensionless>(dto.getTwin().getProperties().getReported().getpM25(), return new QuantityType<Dimensionless>(dto.getProperties().getReported().getPM25(),
Units.PARTS_PER_BILLION); Units.PARTS_PER_BILLION);
case CHANNEL_PM10: case CHANNEL_PM10:
return new QuantityType<Dimensionless>(dto.getTwin().getProperties().getReported().getpM10(), return new QuantityType<Dimensionless>(dto.getProperties().getReported().getPM10(),
Units.PARTS_PER_BILLION); Units.PARTS_PER_BILLION);
case CHANNEL_CO2: case CHANNEL_CO2:
return new QuantityType<Dimensionless>(dto.getTwin().getProperties().getReported().getcO2(), return new QuantityType<Dimensionless>(dto.getProperties().getReported().getCO2(),
Units.PARTS_PER_MILLION); Units.PARTS_PER_MILLION);
case CHANNEL_FAN_SPEED: case CHANNEL_FAN_SPEED:
return new StringType(Integer.toString(dto.getTwin().getProperties().getReported().getFanspeed())); return new StringType(Integer.toString(dto.getProperties().getReported().getFanspeed()));
case CHANNEL_FILTER_LIFE: case CHANNEL_FILTER_LIFE:
return new QuantityType<Dimensionless>(dto.getTwin().getProperties().getReported().getFilterLife(), return new QuantityType<Dimensionless>(dto.getProperties().getReported().getFilterLife(),
Units.PERCENT); Units.PERCENT);
case CHANNEL_IONIZER: case CHANNEL_IONIZER:
return OnOffType.from(dto.getTwin().getProperties().getReported().ionizer); return OnOffType.from(dto.getProperties().getReported().isIonizer());
case CHANNEL_WORK_MODE: case CHANNEL_WORK_MODE:
return new StringType(dto.getTwin().getProperties().getReported().workmode); return new StringType(dto.getProperties().getReported().getWorkmode());
case CHANNEL_DOOR_OPEN: case CHANNEL_DOOR_OPEN:
return dto.getTwin().getProperties().getReported().doorOpen ? OpenClosedType.OPEN return dto.getProperties().getReported().isDoorOpen() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
: OpenClosedType.CLOSED;
} }
return UnDefType.UNDEF; return UnDefType.UNDEF;
} }
@ -196,13 +212,12 @@ public class ElectroluxAirHandler extends BaseThingHandler {
if (bridgeHandler != null) { if (bridgeHandler != null) {
ElectroluxPureA9DTO dto = bridgeHandler.getElectroluxAirThings().get(config.getDeviceId()); ElectroluxPureA9DTO dto = bridgeHandler.getElectroluxAirThings().get(config.getDeviceId());
if (dto != null) { if (dto != null) {
properties.put(Thing.PROPERTY_VENDOR, dto.getApplicancesInfo().brand); properties.put(Thing.PROPERTY_VENDOR, dto.getApplianceInfo().getBrand());
properties.put(PROPERTY_COLOUR, dto.getApplicancesInfo().colour); properties.put(PROPERTY_COLOUR, dto.getApplianceInfo().getColour());
properties.put(PROPERTY_DEVICE, dto.getApplicancesInfo().device); properties.put(PROPERTY_DEVICE, dto.getApplianceInfo().getDeviceType());
properties.put(Thing.PROPERTY_MODEL_ID, dto.getApplicancesInfo().model); properties.put(Thing.PROPERTY_MODEL_ID, dto.getApplianceInfo().getModel());
properties.put(Thing.PROPERTY_SERIAL_NUMBER, dto.getApplicancesInfo().serialNumber); properties.put(Thing.PROPERTY_SERIAL_NUMBER, dto.getApplianceInfo().getSerialNumber());
properties.put(Thing.PROPERTY_FIRMWARE_VERSION, properties.put(Thing.PROPERTY_FIRMWARE_VERSION, dto.getProperties().getReported().getFrmVerNIU());
dto.getTwin().getProperties().getReported().frmVerNIU);
} }
} }
} }

View File

@ -181,5 +181,4 @@
<description>Ionizer Status</description> <description>Ionizer Status</description>
</channel-type> </channel-type>
</thing:thing-descriptions> </thing:thing-descriptions>