forked from openhab/openhab-addons
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[myuplink] Initial contribution (openhab#17451)
* myuplink skeleton Signed-off-by: Alexander Friese <af944580@googlemail.com> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
- Loading branch information
Showing
49 changed files
with
4,369 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
This content is produced and maintained by the openHAB project. | ||
|
||
* Project home: https://www.openhab.org | ||
|
||
== Declared Project Licenses | ||
|
||
This program and the accompanying materials are made available under the terms | ||
of the Eclipse Public License 2.0 which is available at | ||
https://www.eclipse.org/legal/epl-2.0/. | ||
|
||
== Source Code | ||
|
||
https://github.com/openhab/openhab-addons |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# myUplink Binding | ||
|
||
The myUplink binding is used to get "live data" from from Nibe heat pumps without plugging any custom devices into your heat pump. | ||
This avoids the risk of losing your warranty. | ||
Instead data is retrieved from myUplink. | ||
The myUplink API is the successor of the Nibe Uplink API. | ||
This binding should in general be compatible with all heat pump models that support myUplink. | ||
Read or write access is supported by all channels as exposed by the API. | ||
Write access might only be available with a paid subscription for myUplink. | ||
You will need to create credentials at <https://dev.myuplink.com/apps> in order to use this binding. | ||
|
||
## Supported Things | ||
|
||
This binding provides two thing types: | ||
|
||
| Thing/Bridge | Thing Type | Description | | ||
|---------------------|---------------------|-------------------------------------------------------------------| | ||
| bridge | account | cloud connection to a myUplink user account | | ||
| thing | generic-device | the physical heatpump which is connected to myUplink | | ||
## Discovery | ||
|
||
When the `account` bridge is setup, the binding will discover all heatpumps within that account and also detect the specific channels supported by the model. | ||
|
||
## Bridge Configuration | ||
|
||
The following configuration parameters are available for the bridge: | ||
|
||
| Configuration Parameter | Required | Description | | ||
|-------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| clientId | yes | The clientId to login at myUplink cloud service. This is some kind of UUID. Visit <https://dev.myuplink.com/apps> to generate login credentials. | | ||
| clientSecret | yes | The secret which belongs to the clientId. | | ||
| dataPollingInterval | no | Interval (seconds) in which live data values are retrieved from the Easee Cloud API. (default = 60) | | ||
|
||
## Thing Configuration | ||
|
||
It is recommended to use auto discovery which does not require further configuration. | ||
If manual configuration is preferred you need to specify configuration as below. | ||
|
||
| Configuration Parameter | Required | Description | | ||
|-------------------------|----------|------------------------------------------------------------------------------------------------------------------------| | ||
| deviceId | yes | The id of the heatpump that will be represented by this thing. Can be retrieved via API call or autodiscovery. | | ||
| systemId | no | The systemId of the heatpump. Only needed for "SmartHomeMode". Can be retrieved via API call or autodiscovery. | | ||
|
||
## Channels | ||
|
||
The binding only supports channels which are explicitely exposed by the myUplink API. | ||
|
||
Depending on your model and additional hardware the channels might be different. | ||
Thus no list is provided here. | ||
|
||
## Full Example | ||
|
||
The configuration below is an example which could easily be adopted to your actual model. | ||
Thing configuration (account and generic-device) is the same for all models. | ||
Item configuration depends on your specific model and thus channels will have different IDs and/or channels might not exist for all models. | ||
|
||
### `demo.things` Example | ||
|
||
```java | ||
Bridge myuplink:account:myAccount "myUplink" [ | ||
clientId="c7c2f9a4-b960-448f-b00d-b8f30aff3324", | ||
clientSecret="471147114711ABCDEF133713371337AB", | ||
dataPollingInterval=55 | ||
] { | ||
Thing generic-device vvm320 "VVM320" [ deviceId="id taken from automatic discovery", systemId="id taken from automatic discovery" ] | ||
} | ||
``` | ||
|
||
### `demo.items` Example | ||
|
||
```java | ||
Number NIBE_ADD_STATUS "Status ZH [%s]" { channel="myuplink:generic-device:myAccount:vvm320:49993" } | ||
Number NIBE_COMP_STATUS "Status Compr. [%s]" { channel="myuplink:generic-device:myAccount:vvm320:44064" } | ||
Number:Temperature NIBE_SUPPLY "Supply line" { unit="°C", channel="myuplink:generic-device:myAccount:vvm320:40008" } | ||
Number:Temperature NIBE_RETURN "Return line" { unit="°C", channel="myuplink:generic-device:myAccount:vvm320:40012" } | ||
Number:Energy NIBE_HM_HEAT "HM heating" { unit="kWh", channel="myuplink:generic-device:myAccount:vvm320:44308" } | ||
Number:Energy NIBE_HM_HW "HM hot water" { unit="kWh", channel="myuplink:generic-device:myAccount:vvm320:44306" } | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>org.openhab.addons.bundles</groupId> | ||
<artifactId>org.openhab.addons.reactor.bundles</artifactId> | ||
<version>4.3.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>org.openhab.binding.myuplink</artifactId> | ||
|
||
<name>openHAB Add-ons :: Bundles :: myUplink Binding</name> | ||
|
||
</project> |
9 changes: 9 additions & 0 deletions
9
bundles/org.openhab.binding.myuplink/src/main/feature/feature.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<features name="org.openhab.binding.myuplink-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"> | ||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository> | ||
|
||
<feature name="openhab-binding-myuplink" description="myUplink Binding" version="${project.version}"> | ||
<feature>openhab-runtime-base</feature> | ||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.myuplink/${project.version}</bundle> | ||
</feature> | ||
</features> |
59 changes: 59 additions & 0 deletions
59
...ng.myuplink/src/main/java/org/openhab/binding/myuplink/internal/AtomicReferenceTrait.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/** | ||
* Copyright (c) 2010-2024 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.myuplink.internal; | ||
|
||
import java.util.concurrent.Future; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
|
||
/** | ||
* trait class which contains useful helper methods. Thus, the interface can be implemented and methods are available | ||
* within the class. | ||
* | ||
* @author Alexander Friese - initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public interface AtomicReferenceTrait { | ||
|
||
/** | ||
* this should usually not called directly. use updateJobReference or cancelJobReference instead | ||
* | ||
* @param job job to cancel. | ||
*/ | ||
default void cancelJob(@Nullable Future<?> job) { | ||
if (job != null) { | ||
job.cancel(true); | ||
} | ||
} | ||
|
||
/** | ||
* updates a job reference with a new job. the old job will be cancelled if there is one. | ||
* | ||
* @param jobReference reference to be updated | ||
* @param newJob job to be assigned | ||
*/ | ||
default void updateJobReference(AtomicReference<@Nullable Future<?>> jobReference, Future<?> newJob) { | ||
cancelJob(jobReference.getAndSet(newJob)); | ||
} | ||
|
||
/** | ||
* updates a job reference to null and cancels any existing job which might be assigned to the reference. | ||
* | ||
* @param jobReference to be updated to null. | ||
*/ | ||
default void cancelJobReference(AtomicReference<@Nullable Future<?>> jobReference) { | ||
cancelJob(jobReference.getAndSet(null)); | ||
} | ||
} |
181 changes: 181 additions & 0 deletions
181
...yuplink/src/main/java/org/openhab/binding/myuplink/internal/MyUplinkBindingConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/** | ||
* Copyright (c) 2010-2024 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.myuplink.internal; | ||
|
||
import java.time.Instant; | ||
import java.util.Set; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.core.thing.ThingTypeUID; | ||
|
||
/** | ||
* The {@link MyUplinkBindingConstants} class defines common constants, which are | ||
* used across the whole binding. | ||
* | ||
* @author Alexander Friese - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class MyUplinkBindingConstants { | ||
|
||
public static final String BINDING_ID = "myuplink"; | ||
|
||
// List of main device types | ||
public static final String DEVICE_ACCOUNT = "account"; | ||
public static final String DEVICE_GENERIC_DEVICE = "generic-device"; | ||
|
||
// List of all Thing Type UIDs | ||
public static final ThingTypeUID THING_TYPE_ACCOUNT = new ThingTypeUID(BINDING_ID, DEVICE_ACCOUNT); | ||
public static final ThingTypeUID THING_TYPE_GENERIC_DEVICE = new ThingTypeUID(BINDING_ID, DEVICE_GENERIC_DEVICE); | ||
|
||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT, | ||
THING_TYPE_GENERIC_DEVICE); | ||
|
||
// Channel types | ||
public static final String CHANNEL_TYPE_UNIT_NONE = "NO_UNIT"; | ||
public static final String CHANNEL_TYPE_PREFIX_RW = "rw"; | ||
public static final String CHANNEL_TYPE_ENUM_PRFIX = "type-enum-"; | ||
public static final String CHANNEL_TYPE_NUMERIC_PRFIX = "type-numeric-"; | ||
public static final String CHANNEL_TYPE_DEFAULT_DATATYPE = "Number"; | ||
|
||
public static final String CHANNEL_TYPE_ENERGY = "type-energy"; | ||
public static final String CHANNEL_TYPE_ENERGY_UNIT = "kWh"; | ||
public static final String CHANNEL_TYPE_PRESSURE = "type-pressure"; | ||
public static final String CHANNEL_TYPE_PRESSURE_UNIT = "bar"; | ||
public static final String CHANNEL_TYPE_PERCENT = "type-percent"; | ||
public static final String CHANNEL_TYPE_PERCENT_UNIT = "%"; | ||
public static final String CHANNEL_TYPE_TEMPERATURE = "type-temperature"; | ||
public static final String CHANNEL_TYPE_TEMPERATURE_UNIT = "°C"; | ||
public static final String CHANNEL_TYPE_FREQUENCY = "type-frequency"; | ||
public static final String CHANNEL_TYPE_FREQUENCY_UNIT = "Hz"; | ||
public static final String CHANNEL_TYPE_FLOW = "type-flow"; | ||
public static final String CHANNEL_TYPE_FLOW_UNIT = "l/m"; | ||
public static final String CHANNEL_TYPE_ELECTRIC_CURRENT = "type-electric-current"; | ||
public static final String CHANNEL_TYPE_ELECTRIC_CURRENT_UNIT = "A"; | ||
public static final String CHANNEL_TYPE_TIME = "type-time"; | ||
public static final String CHANNEL_TYPE_TIME_UNIT = "h"; | ||
public static final String CHANNEL_TYPE_INTEGER = "type-number-integer"; | ||
public static final String CHANNEL_TYPE_DOUBLE = "type-number-double"; | ||
public static final String CHANNEL_TYPE_ON_OFF = "type-on-off"; | ||
public static final String CHANNEL_TYPE_RW_SWITCH = "rwtype-switch"; | ||
public static final String CHANNEL_TYPE_RW_COMMAND = "rwtype-command"; | ||
public static final String CHANNEL_TYPE_RW_MODE = "rwtype-mode"; | ||
|
||
public static final String CHANNEL_ID_COMMAND = "command"; | ||
public static final String CHANNEL_ID_SMART_HOME_MODE = "smart-home-mode"; | ||
|
||
// JSON Keys | ||
public static final String JSON_KEY_ROOT_DATA = "data"; | ||
public static final String JSON_KEY_CHANNEL_STR_VAL = "strVal"; | ||
public static final String JSON_KEY_CHANNEL_VALUE = "value"; | ||
public static final String JSON_KEY_CHANNEL_WRITABLE = "writable"; | ||
public static final String JSON_KEY_CHANNEL_ENUM_VALUES = "enumValues"; | ||
public static final String JSON_KEY_CHANNEL_ID = "parameterId"; | ||
public static final String JSON_KEY_CHANNEL_LABEL = "parameterName"; | ||
public static final String JSON_KEY_CHANNEL_UNIT = "parameterUnit"; | ||
public static final String JSON_KEY_CHANNEL_SCALE = "scaleValue"; | ||
public static final String JSON_KEY_CHANNEL_MIN = "minValue"; | ||
public static final String JSON_KEY_CHANNEL_MAX = "maxValue"; | ||
public static final String JSON_KEY_CHANNEL_STEP = "stepValue"; | ||
public static final String JSON_KEY_SYSTEMS = "systems"; | ||
public static final String JSON_KEY_SYSTEM_ID = "systemId"; | ||
public static final String JSON_KEY_DEVICES = "devices"; | ||
public static final String JSON_KEY_GENERIC_ID = "id"; | ||
public static final String JSON_KEY_PRODUCT = "product"; | ||
public static final String JSON_KEY_SERIAL = "serialNumber"; | ||
public static final String JSON_KEY_NAME = "name"; | ||
public static final String JSON_KEY_CURRENT_FW_VERSION = "currentFwVersion"; | ||
public static final String JSON_KEY_CONNECTION_STATE = "connectionState"; | ||
public static final String JSON_KEY_ERROR = "error"; | ||
public static final String JSON_KEY_SMART_HOME_MODE = "smartHomeMode"; | ||
|
||
public static final String JSON_KEY_AUTH_ACCESS_TOKEN = "access_token"; | ||
public static final String JSON_KEY_AUTH_EXPIRES_IN = "expires_in"; | ||
|
||
public static final String JSON_ENUM_KEY_TEXT = "text"; | ||
public static final String JSON_ENUM_ORD_0 = "0"; | ||
public static final String JSON_ENUM_ORD_1 = "1"; | ||
public static final String JSON_ENUM_ORD_4 = "4"; | ||
public static final String JSON_ENUM_ORD_6 = "6"; | ||
public static final String JSON_ENUM_ORD_10 = "10"; | ||
public static final String JSON_ENUM_ORD_20 = "20"; | ||
public static final String JSON_ENUM_ORD_30 = "30"; | ||
public static final String JSON_ENUM_ORD_40 = "40"; | ||
public static final String JSON_ENUM_ORD_60 = "60"; | ||
public static final String JSON_ENUM_ORD_100 = "100"; | ||
public static final String JSON_ENUM_VAL_OFF = "off"; | ||
public static final String JSON_ENUM_VAL_ON = "on"; | ||
public static final String JSON_ENUM_VAL_HOT_WATER = "hot water"; | ||
public static final String JSON_ENUM_VAL_HEATING = "heating"; | ||
public static final String JSON_ENUM_VAL_POOL = "pool"; | ||
public static final String JSON_ENUM_VAL_STARTS = "starts"; | ||
public static final String JSON_ENUM_VAL_RUNS = "runs"; | ||
public static final String JSON_ENUM_VAL_ALARM = "alarm"; | ||
public static final String JSON_ENUM_VAL_BLOCKED = "blocked"; | ||
public static final String JSON_ENUM_VAL_ACTIVE = "active"; | ||
|
||
public static final String JSON_VAL_CONNECTION_CONNECTED = "Connected"; | ||
public static final String JSON_VAL_DECIMAL_SEPARATOR = "."; | ||
|
||
// web request constants | ||
public static final long WEB_REQUEST_INITIAL_DELAY = 10; | ||
public static final long WEB_REQUEST_INTERVAL = 5; | ||
public static final int WEB_REQUEST_QUEUE_MAX_SIZE = 20; | ||
public static final int WEB_REQUEST_TOKEN_EXPIRY_BUFFER_MINUTES = 5; | ||
public static final int WEB_REQUEST_TOKEN_MAX_AGE_MINUTES = 45; | ||
public static final String WEB_REQUEST_PARAM_PAGE_KEY = "page"; | ||
public static final String WEB_REQUEST_PARAM_PAGE_SIZE_KEY = "itemsPerPage"; | ||
public static final String WEB_REQUEST_PATCH_CONTENT_TYPE = "application/json-patch+json"; | ||
public static final int WEB_REQUEST_PARAM_PAGE_SIZE_VALUE = 100; | ||
public static final String WEB_REQUEST_BEARER_TOKEN_PREFIX = "Bearer "; | ||
public static final String LOGIN_BASIC_AUTH_PREFIX = "Basic "; | ||
public static final String LOGIN_FIELD_SCOPE_KEY = "scope"; | ||
public static final String LOGIN_FIELD_SCOPE_VALUE = "READSYSTEM WRITESYSTEM"; | ||
public static final String LOGIN_FIELD_GRANT_TYPE_KEY = "grant_type"; | ||
public static final String LOGIN_FIELD_GRANT_TYPE_VALUE = "client_credentials"; | ||
|
||
// URLs | ||
private static final String API_BASE_URL = "https://api.myuplink.com"; | ||
public static final String LOGIN_URL = API_BASE_URL + "/oauth/token"; | ||
public static final String GET_SYSTEMS_URL = API_BASE_URL + "/v2/systems/me"; | ||
public static final String GET_SMART_HOME_MODE_URL = API_BASE_URL + "/v2/systems/{systemId}/smart-home-mode"; | ||
public static final String SET_SMART_HOME_MODE_URL = GET_SMART_HOME_MODE_URL; | ||
public static final String GET_DEVICE_POINTS = API_BASE_URL + "/v2/devices/{deviceId}/points"; | ||
public static final String SET_DEVICE_POINTS = GET_DEVICE_POINTS; | ||
|
||
// Status Keys | ||
public static final String STATUS_TOKEN_VALIDATED = "@text/status.token.validated"; | ||
public static final String STATUS_WAITING_FOR_BRIDGE = "@text/status.waiting.for.bridge"; | ||
public static final String STATUS_WAITING_FOR_LOGIN = "@text/status.waiting.for.login"; | ||
public static final String STATUS_NO_VALID_DATA = "@text/status.no.valid.data"; | ||
public static final String STATUS_NO_CONNECTION = "@text/status.no.connection"; | ||
public static final String STATUS_DEVICE_NOT_FOUND = "@text/status.device.not.found"; | ||
public static final String STATUS_CONFIG_ERROR_NO_CLIENT_ID = "@text/status.config.error.no.client.id"; | ||
public static final String STATUS_CONFIG_ERROR_NO_CLIENT_SECRET = "@text/status.config.error.no.client.secret"; | ||
|
||
// other | ||
public static final long POLLING_INITIAL_DELAY = 5; | ||
|
||
public static final String GENERIC_NO_VAL = "---"; | ||
public static final String EMPTY = ""; | ||
|
||
public static final String THING_CONFIG_ID = "deviceId"; | ||
public static final String THING_CONFIG_SYSTEM_ID = "systemId"; | ||
public static final String THING_CONFIG_SERIAL = "serial"; | ||
public static final String THING_CONFIG_CURRENT_FW_VERSION = "currentFwVersion"; | ||
|
||
public static final Instant OUTDATED_DATE = Instant.EPOCH; | ||
|
||
public static final String PARAMETER_NAME_WRITE_COMMAND = "writeCommand"; | ||
public static final String PARAMETER_NAME_VALIDATION_REGEXP = "validationExpression"; | ||
public static final String DEFAULT_VALIDATION_EXPRESSION = "[0-9]+"; | ||
} |
Oops, something went wrong.