Skip to content

Commit

Permalink
[intesis] - added IntesisBox support (openhab#8694)
Browse files Browse the repository at this point in the history
* Intesis Binding - added IntesisBox support
  • Loading branch information
hmerk committed Oct 24, 2020
1 parent 3e3e086 commit bd10f7d
Show file tree
Hide file tree
Showing 16 changed files with 900 additions and 43 deletions.
55 changes: 30 additions & 25 deletions bundles/org.openhab.binding.intesis/README.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,68 @@
# Intesis Binding

This binding connects to WiFi [IntesisHome](http://www.intesishome.com/) devices using their local REST Api.
It does actually not support [IntesisBox](http://www.intesisbox.com/) devices but support is planned in upcoming version.
This binding connects to WiFi [IntesisHome](https://www.intesis.com/products/cloud-solutions/ac-cloud-control) devices using their local REST Api and to [IntesisBox](https://www.intesis.com/products/ac-interfaces/wifi-gateways) devices using TCP connection.



## Supported Things

This binding only supports one thing type:

| Thing | Thing Type | Description |
|------------ |------------|---------------------------------|
| intesisHome | Thing | Represents a single WiFi device |
| Thing | Thing Type | Description |
|-------------|------------|---------------------------------------------|
| intesisHome | Thing | Represents a single IntesisHome WiFi device |
| intesisBox | Thing | Represents a single IntesisBox WiFi device |

## Discovery

Intesis devices do not support auto discovery.

## Thing Configuration

The binding needs two configuration parameters.
The binding uses the following configuration parameters.

| Parameter | Description |
|-----------|---------------------------------------------------|
| ipAddress | IP-Address of the device |
| password | Password to login to the local webserver of device |
| Parameter | Valid for ThingType | Description |
|-----------|---------------------|----------------------------------------------------------------|
| ipAddress | Both | IP-Address of the device |
| password | IntesisHome | Password to login to the local webserver of IntesisHome device |
| port | IntesisBox | TCP port to connect to IntesisBox device, defaults to 3310 |


## Channels

| Channel ID | Item Type | Description | Possible Values |
|--------------------|--------------------|---------------------------------------------|---------------------------|
| power | Switch | Turns power on/off for your climate system. | ON, OFF |
| mode | String | The heating/cooling mode. | AUTO,HEAT,DRY,FAN,COOL |
| fanSpeed | String | Fan speed (if applicable) | AUTO,1-10 |
| vanesUpDown | String | Control of up/down vanes (if applicable) | AUTO,1-9,SWING,SWIRL,WIDE |
| vanesUpDown | String | Control of left/right vanes (if applicable) | AUTO,1-9,SWING,SWIRL,WIDE |
| targetTemperature | Number:Temperature | The currently set target temperature. | |
| ambientTemperature | Number:Temperature | (Readonly) The ambient air temperature. | |
| outdoorTemperature | Number:Temperature | (Readonly) The outdoor air temperature. | |
| Channel ID | Item Type | Description | Possible Values |
|--------------------|--------------------|--------------------------------------------------------|---------------------------------------------------------|
| power | Switch | Turns power on/off for your climate system. | ON,OFF |
| mode | String | The heating/cooling mode. | AUTO,HEAT,DRY,FAN,COOL |
| fanSpeed | String | Fan speed (if applicable) | AUTO,1-10 |
| vanesUpDown | String | Control of up/down vanes (if applicable) | AUTO,1-9,SWING,SWIRL,WIDE |
| vanesUpDown | String | Control of left/right vanes (if applicable) | AUTO,1-9,SWING,SWIRL,WIDE |
| targetTemperature | Number:Temperature | The currently set target temperature (if applicable) | range between 18°C and 30°C |
| ambientTemperature | Number:Temperature | (Readonly) The ambient air temperature (if applicable) | |
| outdoorTemperature | Number:Temperature | (Readonly) The outdoor air temperature (if applicable) | |
| errorStatus | String | (Readonly) The error status of the device | OK,ERR |
| errorCode | String | (Readonly) The error code if an error encountered | not documented |
| wifiSignal | Number | (Readonly) WiFi signal strength (IntesisBox only) | 4=excellent, 3=good, 2=not string, 1=unreliable, 0=none |

Note that individual A/C units may not support all channels, or all possible values for those channels.

The binding will add all supported channels and possible values on first thing initialization and list them as thing properties.
If new channels or values might be supported after firmware upgrades, deleting the thing and reading is necessary.
For example, not all A/C units have controllable vanes. Or fan speed may be limited to 1-4, instead of all of 1-9.
The set point temperature is also limited to a device specific range. For set point temperature, sending an invalid value
If new channels or values might be supported after firmware upgrades, deleting the thing and re-adding is necessary.
For example, not all A/C units have controllable vanes or fan speed may be limited to 1-4, instead of all of 1-9.
The target temperature is also limited to a device specific range. For target temperature, sending an invalid value
will cause it to choose the minimum/maximum allowable value as appropriate. The device will also round it to
whatever step size it supports. For all other channels, invalid values are ignored.
IntesisBox firmware 1.3.3 reports temperatures by full degrees only (e.g. 23.0) even if a half degree (e.g. 23.5) was set.

## Full Example

The binding can be fully setup from the UI but if you decide to use files here is a full example:

**Things**

```intesisHome.things
```
Thing intesis:intesisHome:acOffice "AC Unit Adapter" @ "AC" [ipAddress="192.168.1.100", password="xxxxx"]
Thing intesis:intesisBox:acOffice "AC Unit Adapter" @ "AC" [ipAddress="192.168.1.100", port=3310]
```

**Items**
Expand Down Expand Up @@ -89,4 +95,3 @@ sitemap intesishome label="My AC control" {
}
}
```

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class IntesisBindingConstants {

// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_INTESISHOME = new ThingTypeUID(BINDING_ID, "intesisHome");
public static final ThingTypeUID THING_TYPE_INTESISBOX = new ThingTypeUID(BINDING_ID, "intesisBox");

// List of all Channel ids
public static final String CHANNEL_TYPE_POWER = "power";
Expand All @@ -41,4 +42,7 @@ public class IntesisBindingConstants {
public static final String CHANNEL_TYPE_TARGETTEMP = "targetTemperature";
public static final String CHANNEL_TYPE_AMBIENTTEMP = "ambientTemperature";
public static final String CHANNEL_TYPE_OUTDOORTEMP = "outdoorTemperature";
public static final String CHANNEL_TYPE_ERRORCODE = "errorCode";
public static final String CHANNEL_TYPE_ERRORSTATUS = "errorStatus";
public static final String CHANNEL_TYPE_RSSI = "wifiSignal";
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
*/
package org.openhab.binding.intesis.internal;

import static org.openhab.binding.intesis.internal.IntesisBindingConstants.THING_TYPE_INTESISHOME;
import static org.openhab.binding.intesis.internal.IntesisBindingConstants.*;

import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.intesis.internal.handler.IntesisBoxHandler;
import org.openhab.binding.intesis.internal.handler.IntesisHomeHandler;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Thing;
Expand Down Expand Up @@ -48,7 +51,8 @@ public class IntesisHandlerFactory extends BaseThingHandlerFactory {
private final HttpClient httpClient;
private final IntesisDynamicStateDescriptionProvider intesisStateDescriptionProvider;

private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_INTESISHOME);
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
.unmodifiableSet(Stream.of(THING_TYPE_INTESISHOME, THING_TYPE_INTESISBOX).collect(Collectors.toSet()));

@Activate
public IntesisHandlerFactory(@Reference HttpClientFactory httpClientFactory, ComponentContext componentContext,
Expand All @@ -69,10 +73,13 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (THING_TYPE_INTESISHOME.equals(thingTypeUID)) {
logger.debug("Creating a IntesisHomeHandler for thing '{}'", thing.getUID());
return new IntesisHomeHandler(thing, httpClient, intesisStateDescriptionProvider);
}

if (THING_TYPE_INTESISBOX.equals(thingTypeUID)) {
return new IntesisBoxHandler(thing, intesisStateDescriptionProvider);
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2010-2020 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.intesis.internal.api;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.ThingStatus;

/**
* The {@link IntesisBoxChangeListener} is in interface for a IntesisBox changed consumer
*
* @author Hans-Jörg Merk - Initial contribution
*/
@NonNullByDefault
public interface IntesisBoxChangeListener {
/**
* This method will be called in case a message was received.
*
*/
void messageReceived(String messageLine);

/**
* This method will be called in case the connection status has changed.
*
*/
void connectionStatusChanged(ThingStatus status, @Nullable String message);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright (c) 2010-2020 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.intesis.internal.api;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;

/**
* @author Cody Cutrer - Initial contribution
*/
@NonNullByDefault
public class IntesisBoxMessage {
public static final String ID = "ID";
public static final String INFO = "INFO";
public static final String SET = "SET";
public static final String CHN = "CHN";
public static final String GET = "GET";
public static final String LOGIN = "LOGIN";
public static final String LOGOUT = "LOGOUT";
public static final String CFG = "CFG";
public static final String LIMITS = "LIMITS";
public static final String DISCOVER = "DISCOVER";

private static final Pattern REGEX = Pattern.compile("^([^,]+)(?:,(\\d+))?:([^,]+),([A-Z0-9.,\\[\\]]+)$");

@SuppressWarnings("unused")
private final String acNum;
private final String command;
private final String function;
private final String value;

private IntesisBoxMessage(String command, String acNum, String function, String value) {
this.command = command;
this.acNum = acNum;
this.function = function;
this.value = value;
}

public String getCommand() {
return command;
}

public String getFunction() {
return function;
}

public String getValue() {
return value;
}

public List<String> getLimitsValue() {
return Arrays.asList(value.substring(1, value.length() - 1).split(","));
}

public static @Nullable IntesisBoxMessage parse(String message) {
Matcher m = REGEX.matcher(message);
if (!m.find()) {
return null;
}

return new IntesisBoxMessage(m.group(1), m.group(2), m.group(3), m.group(4));
}
}
Loading

0 comments on commit bd10f7d

Please sign in to comment.