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

[tado] Add channel for PresenceState and support setting HOME/AWAY. Fixes #8826 #8854

Closed
wants to merge 1 commit into from
Closed
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
13 changes: 12 additions & 1 deletion bundles/org.openhab.binding.tado/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
The tado° binding integrates devices from [tado°](https://www.tado.com).

It requires a fully functional tado° installation.
You can then monitor and control all zone types (Heating, AC, Hot Water) as well as retrieve the HOME/AWAY status of mobile devices.
You can then monitor and control all zone types (Heating, AC, Hot Water) as well as retrieve the HOME/AWAY status of mobile devices, and setting the HOME/AWAY status of your home.

## `home` Thing (the Bridge)

Expand All @@ -24,6 +24,12 @@ Bridge tado:home:demo [ username="mail@example.com", password="secret" ]

Afterwards the discovery will show all zones and mobile devices associated with the user's home.

### Channels

Name | Type | Description | Read/Write
-|-|-|-|-
`homePresence` | String | Current presence value of the tado home. `HOME` and `AWAY` can be set | RW

## `zone` Thing

A *zone* is an area/room of your home.
Expand Down Expand Up @@ -143,6 +149,7 @@ Bridge tado:home:demo [ username="mail@example.com", password="secret" ] {
## tado.items

```
Switch TADO_PRESENCE_home "Tado Presence: [MAP(presence.map):%s]" { channel="tado:home:demo:homePresence" }
Number:Temperature HEAT_inside_temperature "Inside Temperature" { channel="tado:zone:demo:heating:currentTemperature" }
Number HEAT_humidity "Humidity" { channel="tado:zone:demo:heating:humidity" }
Number HEAT_heating_power "Heating Power" { channel="tado:zone:demo:heating:heatingPower" }
Expand Down Expand Up @@ -179,6 +186,10 @@ Switch Phone_atHome "Phone location [MAP(presence.map)
```
sitemap tado label="Tado"
{
Frame label="Status" {
Switch item=TADO_PRESENCE_home icon="presence"
}

Frame label="Heating" {
Text item=HEAT_inside_temperature
Text item=HEAT_humidity
Expand Down
2 changes: 1 addition & 1 deletion bundles/org.openhab.binding.tado/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<dependency>
<groupId>org.openhab.binding.tado</groupId>
<artifactId>api-client</artifactId>
<version>1.3.0</version>
<version>1.4.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
Expand Down
2 changes: 1 addition & 1 deletion bundles/org.openhab.binding.tado/src/main/api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.openhab.binding.tado</groupId>
<artifactId>api-client</artifactId>
<version>1.3.0</version>
<version>1.4.1</version>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
Expand Down
94 changes: 94 additions & 0 deletions bundles/org.openhab.binding.tado/src/main/api/tado-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,62 @@ paths:
404:
$ref: "#/responses/NotFound"

/homes/{home_id}/state:
get:
operationId: homeState
summary: Get state of home
tags:
- home
security:
- oauth:
- home.details:read
description: This will the current presence state of the home (HOME/AWAY).
parameters:
- $ref: "#/parameters/homeID"
responses:
200:
description: Home State
schema:
$ref: "#/definitions/HomeState"
401:
$ref: "#/responses/Unauthorized"
403:
$ref: "#/responses/AccessDenied"
404:
$ref: "#/responses/NotFound"

/homes/{home_id}/presenceLock:
put:
operationId: updatePresenceLock
summary: Set a presence lock state, i.e., HOME or AWAY
tags:
- home
security:
- oauth:
- home.operation:write
description: This will set the presence mode of the home
parameters:
- $ref: "#/parameters/homeID"
- name: json
in: body
description: The new presence settings.
required: true
schema:
$ref: "#/definitions/HomePresence"
responses:
200:
description: Presence mode successfully updated.
400:
$ref: "#/responses/BadRequest"
401:
$ref: "#/responses/Unauthorized"
403:
$ref: "#/responses/AccessDenied"
404:
$ref: "#/responses/NotFound"
422:
$ref: "#/responses/UnprocessableEntity"

/homes/{home_id}/zones:
get:
operationId: listZones
Expand Down Expand Up @@ -368,6 +424,37 @@ definitions:
- temperatureUnit
- awayRadiusInMeters

HomeState:
type: object
properties:
presence:
description: Presence State.
$ref: "#/definitions/PresenceState"
name:
description: User defined name for the home.
type: string
readOnly: true
presenceLocked:
description: Not sure what this does..
type: boolean
readOnly: true
showHomePresenceSwitchButton:
description: Not sure what this does..
type: boolean
readOnly: true
required:
- presence
- presenceLocked

HomePresence:
type: object
properties:
homePresence:
description: Presence State.
$ref: "#/definitions/PresenceState"
required:
- homePresence

TadoSystemType:
description: The system type of the zone.
type: string
Expand Down Expand Up @@ -426,6 +513,13 @@ definitions:
- 'ON'
- 'OFF'

PresenceState:
type: string
description: Enum to represent presence state.
enum:
- 'HOME'
- 'AWAY'

GenericZoneSetting:
type: object
discriminator: type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public static enum TemperatureUnit {
FAHRENHEIT
}

public static final String CHANNEL_HOME_PRESENCE_MODE = "homePresence";

public static final String CHANNEL_ZONE_CURRENT_TEMPERATURE = "currentTemperature";
public static final String CHANNEL_ZONE_HUMIDITY = "humidity";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,24 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.eclipse.smarthome.core.library.types.OnOffType;
import org.eclipse.smarthome.core.thing.Bridge;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.ThingStatusDetail;
import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.types.State;
import org.openhab.binding.tado.internal.TadoBindingConstants;
import org.openhab.binding.tado.internal.TadoBindingConstants.TemperatureUnit;
import org.openhab.binding.tado.internal.api.ApiException;
import org.openhab.binding.tado.internal.api.HomeApiFactory;
import org.openhab.binding.tado.internal.api.client.HomeApi;
import org.openhab.binding.tado.internal.api.model.HomeInfo;
import org.openhab.binding.tado.internal.api.model.HomePresence;
import org.openhab.binding.tado.internal.api.model.HomeState;
import org.openhab.binding.tado.internal.api.model.PresenceState;
import org.openhab.binding.tado.internal.api.model.User;
import org.openhab.binding.tado.internal.config.TadoHomeConfig;
import org.slf4j.Logger;
Expand Down Expand Up @@ -126,9 +131,45 @@ public Long getHomeId() {
return homeId;
}

public HomeState getHomeState() throws IOException, ApiException {
HomeApi api = getApi();
return api != null ? api.homeState(getHomeId()) : null;
}

public void updateHomeState() {
try {
updateState(TadoBindingConstants.CHANNEL_HOME_PRESENCE_MODE,
getHomeState().getPresence() == PresenceState.HOME ? OnOffType.ON : OnOffType.OFF);
} catch (IOException | ApiException e) {
logger.debug("Error accessing tado server: {}", e.getMessage(), e);
}
}

@Override
public void handleCommand(ChannelUID channelUID, Command command) {
// Nothing to do for a bridge
String id = channelUID.getId();

if (command == RefreshType.REFRESH) {
updateHomeState();
return;
}

switch (id) {
case TadoBindingConstants.CHANNEL_HOME_PRESENCE_MODE:
HomePresence presence = new HomePresence();
presence.setHomePresence(
command.toFullString().toUpperCase().equals("ON") ||
command.toFullString().toUpperCase().equals("HOME") ?
PresenceState.HOME : PresenceState.AWAY);
try {
api.updatePresenceLock(homeId, presence);
} catch (IOException | ApiException e) {
logger.warn("Error setting home presence: {}", e.getMessage(), e);
}

break;

}
}

public State getBatteryLowAlarm(long zoneId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
}

private void updateZoneState(boolean forceUpdate) {
TadoHomeHandler home = getHomeHandler();
if (home != null) {
home.updateHomeState();
}

// No update during HVAC change debounce
if (!forceUpdate && scheduledHvacChange != null && !scheduledHvacChange.isDone()) {
return;
Expand Down Expand Up @@ -258,7 +263,6 @@ private void updateZoneState(boolean forceUpdate) {
"Could not connect to server due to " + e.getMessage());
}

TadoHomeHandler home = getHomeHandler();
if (home != null) {
updateState(TadoBindingConstants.CHANNEL_ZONE_BATTERY_LOW_ALARM, home.getBatteryLowAlarm(getZoneId()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
<label>Tado Home</label>
<description>The user's tado home</description>

<channels>
<channel typeId="homePresence" id="homePresence"></channel>
</channels>

<config-description>
<parameter name="username" type="text" required="true">
<label>User Name</label>
Expand Down Expand Up @@ -108,6 +112,12 @@
</config-description>
</thing-type>

<channel-type id="homePresence">
<item-type>Switch</item-type>
<label>At Home</label>
<description>ON if at home, OFF if away</description>
</channel-type>

<channel-type id="currentTemperature">
<item-type>Number:Temperature</item-type>
<label>Temperature</label>
Expand Down