added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.nibeuplink-${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-nibeuplink" description="NibeUplink Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.nibeuplink/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.nibeuplink.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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link NibeUplinkBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public final class NibeUplinkBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = "nibeuplink";
|
||||
|
||||
// List of main device types
|
||||
public static final String DEVICE_VVM320 = "vvm320";
|
||||
public static final String DEVICE_VVM310 = "vvm310";
|
||||
public static final String DEVICE_F730 = "f730";
|
||||
public static final String DEVICE_F750 = "f750";
|
||||
public static final String DEVICE_F1145 = "f1145";
|
||||
public static final String DEVICE_F1155 = "f1155";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_VVM320 = new ThingTypeUID(BINDING_ID, DEVICE_VVM320);
|
||||
public static final ThingTypeUID THING_TYPE_VVM310 = new ThingTypeUID(BINDING_ID, DEVICE_VVM310);
|
||||
public static final ThingTypeUID THING_TYPE_F730 = new ThingTypeUID(BINDING_ID, DEVICE_F730);
|
||||
public static final ThingTypeUID THING_TYPE_F750 = new ThingTypeUID(BINDING_ID, DEVICE_F750);
|
||||
public static final ThingTypeUID THING_TYPE_F1145 = new ThingTypeUID(BINDING_ID, DEVICE_F1145);
|
||||
public static final ThingTypeUID THING_TYPE_F1155 = new ThingTypeUID(BINDING_ID, DEVICE_F1155);
|
||||
|
||||
public static final String VALID_CHANNEL_ID_REGEX = "[1-5][0-9][0-9][0-9][0-9]";
|
||||
|
||||
public static final String PARAMETER_NAME_WRITE_API_URL = "writeApiUrl";
|
||||
public static final String PARAMETER_NAME_VALIDATION_REGEXP = "validationExpression";
|
||||
public static final String PARAMETER_NAME_OFF_MAPPING = "offMapping";
|
||||
public static final String PARAMETER_NAME_ON_MAPPING = "onMapping";
|
||||
|
||||
// List of all channel types
|
||||
public static final String CHANNEL_TYPE_NUMBER_UNSCALED = "type-number-unscaled";
|
||||
public static final String CHANNEL_TYPE_NUMBER_SCALE10 = "type-number-scale10";
|
||||
public static final String CHANNEL_TYPE_NUMBER_SCALE100 = "type-number-scale100";
|
||||
public static final String CHANNEL_TYPE_TEMPERATURE = "type-temperature";
|
||||
public static final String CHANNEL_TYPE_SWITCH = "type-switch";
|
||||
public static final String CHANNEL_TYPE_POWER = "type-power";
|
||||
public static final String CHANNEL_TYPE_ENERGY = "type-energy";
|
||||
public static final String CHANNEL_TYPE_ELECTRIC_CURRENT = "type-electric-current";
|
||||
public static final String CHANNEL_TYPE_TIME_UNSCALED = "type-time-unscaled";
|
||||
public static final String CHANNEL_TYPE_TIME_SCALE10 = "type-time-scale10";
|
||||
public static final String CHANNEL_TYPE_FREQUENCY_UNSCALED = "type-frequency-unscaled";
|
||||
public static final String CHANNEL_TYPE_FREQUENCY_SCALE10 = "type-frequency-scale10";
|
||||
public static final String CHANNEL_TYPE_FLOW = "type-flow";
|
||||
public static final String CHANNEL_TYPE_SPEED = "type-speed-percent";
|
||||
public static final String CHANNEL_TYPE_DEFROSTING_STATE = "type-defrosting-state";
|
||||
public static final String CHANNEL_TYPE_HPAC_STATE = "type-hpac-state";
|
||||
public static final String CHANNEL_TYPE_PRESSURE = "type-pressure";
|
||||
|
||||
public static final String RW_CHANNEL_PREFIX = "rw";
|
||||
public static final String CHANNEL_TYPE_HEAT_OFFSET_RW = "rwtype-heat-offset";
|
||||
public static final String CHANNEL_TYPE_START_COOLING_RW = "rwtype-start-cooling";
|
||||
public static final String CHANNEL_TYPE_STOP_HEATING_RW = "rwtype-stop-heating";
|
||||
public static final String CHANNEL_TYPE_STOP_ADD_HEATING_RW = "rwtype-stop-add-heating";
|
||||
public static final String CHANNEL_TYPE_FILTER_TIME_RW = "rwtype-filter-time";
|
||||
public static final String CHANNEL_TYPE_ROOM_SENSOR_FACTOR_RW = "rwtype-room-sensor-factor";
|
||||
public static final String CHANNEL_TYPE_SWITCH_RW = "rwtype-switch";
|
||||
public static final String CHANNEL_TYPE_DEGREE_MINUTES_RW = "rwtype-degree-minutes";
|
||||
public static final String CHANNEL_TYPE_HW_LUX_RW = "rwtype-hw-lux";
|
||||
public static final String CHANNEL_TYPE_HW_MODE_RW = "rwtype-hw-mode";
|
||||
public static final String CHANNEL_TYPE_FAN_SPEED_RW = "rwtype-fan-speed";
|
||||
|
||||
// URLs
|
||||
public static final String LOGIN_URL = "https://www.nibeuplink.com/LogIn";
|
||||
public static final String DATA_API_URL = "https://www.nibeuplink.com/PrivateAPI/QueueValues";
|
||||
public static final String MANAGE_API_BASE_URL = "https://www.nibeuplink.com/System/";
|
||||
|
||||
// login field names
|
||||
public static final String LOGIN_FIELD_PASSWORD = "Password";
|
||||
public static final String LOGIN_FIELD_EMAIL = "Email";
|
||||
public static final String LOGIN_FIELD_RETURN_URL = "returnUrl";
|
||||
|
||||
// other field names
|
||||
public static final String DATA_API_FIELD_LAST_DATE = "currentWebDate";
|
||||
public static final String DATA_API_FIELD_LAST_DATE_DEFAULT_VALUE = "01.01.2017 13:37:42";
|
||||
public static final String DATA_API_FIELD_ID = "hpid";
|
||||
public static final String DATA_API_FIELD_DATA = "variables";
|
||||
public static final String DATA_API_FIELD_DATA_DEFAULT_VALUE = "0";
|
||||
|
||||
// web request constants
|
||||
public static final long WEB_REQUEST_INITIAL_DELAY = TimeUnit.SECONDS.toMillis(30);
|
||||
public static final long WEB_REQUEST_INTERVAL = TimeUnit.SECONDS.toMillis(5);
|
||||
public static final int WEB_REQUEST_QUEUE_MAX_SIZE = 20;
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
|
||||
.unmodifiableSet(Stream.of(THING_TYPE_VVM320, THING_TYPE_VVM310, THING_TYPE_F730, THING_TYPE_F750,
|
||||
THING_TYPE_F1145, THING_TYPE_F1155).collect(Collectors.toSet()));
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal;
|
||||
|
||||
import static org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants.SUPPORTED_THING_TYPES_UIDS;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.GenericHandler;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link NibeUplinkHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.nibeuplink")
|
||||
@NonNullByDefault
|
||||
public class NibeUplinkHandlerFactory extends BaseThingHandlerFactory {
|
||||
private final Logger logger = LoggerFactory.getLogger(NibeUplinkHandlerFactory.class);
|
||||
|
||||
/**
|
||||
* the shared http client
|
||||
*/
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
public NibeUplinkHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (supportsThingType(thingTypeUID)) {
|
||||
return new GenericHandler(thing, httpClient);
|
||||
} else {
|
||||
logger.warn("Unsupported Thing-Type: {}", thingTypeUID.getAsString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.callback;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpStatus.Code;
|
||||
import org.openhab.binding.nibeuplink.internal.command.NibeUplinkCommand;
|
||||
import org.openhab.binding.nibeuplink.internal.config.NibeUplinkConfiguration;
|
||||
import org.openhab.binding.nibeuplink.internal.connector.CommunicationStatus;
|
||||
import org.openhab.binding.nibeuplink.internal.connector.StatusUpdateListener;
|
||||
import org.openhab.binding.nibeuplink.internal.model.GenericDataResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* base class for all commands. common logic should be implemented here
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractUplinkCommandCallback extends BufferingResponseListener implements NibeUplinkCommand {
|
||||
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
protected final Logger logger = LoggerFactory.getLogger(AbstractUplinkCommandCallback.class);
|
||||
|
||||
/**
|
||||
* the configuration
|
||||
*/
|
||||
protected final NibeUplinkConfiguration config;
|
||||
|
||||
/**
|
||||
* status code of fulfilled request
|
||||
*/
|
||||
private CommunicationStatus communicationStatus;
|
||||
|
||||
/**
|
||||
* listener to provide updates to the WebInterface class
|
||||
*/
|
||||
private @Nullable StatusUpdateListener listener;
|
||||
|
||||
/**
|
||||
* JSON deserializer
|
||||
*/
|
||||
private final Gson gson;
|
||||
|
||||
/**
|
||||
* the constructor
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
public AbstractUplinkCommandCallback(NibeUplinkConfiguration config) {
|
||||
this.communicationStatus = new CommunicationStatus();
|
||||
this.config = config;
|
||||
this.gson = new Gson();
|
||||
}
|
||||
|
||||
/**
|
||||
* the constructor
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
public AbstractUplinkCommandCallback(NibeUplinkConfiguration config, StatusUpdateListener listener) {
|
||||
this(config);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log request success
|
||||
*/
|
||||
@Override
|
||||
public final void onSuccess(@Nullable Response response) {
|
||||
super.onSuccess(response);
|
||||
if (response != null) {
|
||||
communicationStatus.setHttpCode(HttpStatus.getCode(response.getStatus()));
|
||||
logger.debug("HTTP response {}", response.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log request failure
|
||||
*/
|
||||
@Override
|
||||
public final void onFailure(@Nullable Response response, @Nullable Throwable failure) {
|
||||
super.onFailure(response, failure);
|
||||
if (failure != null) {
|
||||
logger.debug("Request failed: {}", failure.toString());
|
||||
communicationStatus.setError((Exception) failure);
|
||||
|
||||
if (failure instanceof SocketTimeoutException || failure instanceof TimeoutException) {
|
||||
communicationStatus.setHttpCode(Code.REQUEST_TIMEOUT);
|
||||
} else if (failure instanceof UnknownHostException) {
|
||||
communicationStatus.setHttpCode(Code.BAD_GATEWAY);
|
||||
} else {
|
||||
communicationStatus.setHttpCode(Code.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContent(@Nullable Response response, @Nullable ByteBuffer content) {
|
||||
super.onContent(response, content);
|
||||
logger.debug("received content, length: {}", getContentAsString().length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction(HttpClient asyncclient) {
|
||||
Request request = asyncclient.newRequest(getURL()).timeout(config.getAsyncTimeout(), TimeUnit.SECONDS);
|
||||
prepareRequest(request).send(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Nullable wrapper of gson which does not 'understand' nonnull annotations
|
||||
*
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
protected @Nullable GenericDataResponse fromJson(String json) {
|
||||
// gson is not able to handle @NonNull annotation, thus the return value can be null.
|
||||
return gson.fromJson(json, GenericDataResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns Http Status Code
|
||||
*/
|
||||
public CommunicationStatus getCommunicationStatus() {
|
||||
return communicationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* concrete implementation has to prepare the requests with additional parameters, etc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract Request prepareRequest(Request requestToPrepare);
|
||||
|
||||
/**
|
||||
* concrete implementation has to provide the URL
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract String getURL();
|
||||
|
||||
@Override
|
||||
public final @Nullable StatusUpdateListener getListener() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setListener(StatusUpdateListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.command;
|
||||
|
||||
import static org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants.*;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.FormContentProvider;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.openhab.binding.nibeuplink.internal.callback.AbstractUplinkCommandCallback;
|
||||
import org.openhab.binding.nibeuplink.internal.connector.StatusUpdateListener;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.NibeUplinkHandler;
|
||||
import org.openhab.binding.nibeuplink.internal.model.DataResponse;
|
||||
import org.openhab.binding.nibeuplink.internal.model.DataResponseTransformer;
|
||||
import org.openhab.core.thing.Channel;
|
||||
|
||||
/**
|
||||
* generic command that retrieves status values for all channels defined in {@link VVM320Channels}
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GenericStatusUpdate extends AbstractUplinkCommandCallback implements NibeUplinkCommand {
|
||||
private final NibeUplinkHandler handler;
|
||||
private final DataResponseTransformer transformer;
|
||||
private int retries = 0;
|
||||
|
||||
public GenericStatusUpdate(NibeUplinkHandler handler) {
|
||||
super(handler.getConfiguration());
|
||||
this.handler = handler;
|
||||
this.transformer = new DataResponseTransformer(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Request prepareRequest(Request requestToPrepare) {
|
||||
Fields fields = new Fields();
|
||||
fields.add(DATA_API_FIELD_LAST_DATE, DATA_API_FIELD_LAST_DATE_DEFAULT_VALUE);
|
||||
fields.add(DATA_API_FIELD_ID, config.getNibeId());
|
||||
|
||||
for (Channel channel : handler.getChannels()) {
|
||||
if (!handler.getDeadChannels().contains(channel)) {
|
||||
fields.add(DATA_API_FIELD_DATA, channel.getUID().getIdWithoutGroup());
|
||||
}
|
||||
}
|
||||
|
||||
fields.add(DATA_API_FIELD_DATA, DATA_API_FIELD_DATA_DEFAULT_VALUE);
|
||||
FormContentProvider cp = new FormContentProvider(fields);
|
||||
|
||||
requestToPrepare.header(HttpHeader.ACCEPT, "application/json");
|
||||
requestToPrepare.header(HttpHeader.ACCEPT_ENCODING, StandardCharsets.UTF_8.name());
|
||||
requestToPrepare.content(cp);
|
||||
requestToPrepare.followRedirects(false);
|
||||
requestToPrepare.method(HttpMethod.POST);
|
||||
|
||||
return requestToPrepare;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getURL() {
|
||||
return DATA_API_URL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@Nullable Result result) {
|
||||
logger.debug("onComplete()");
|
||||
|
||||
if (!HttpStatus.Code.OK.equals(getCommunicationStatus().getHttpCode()) && retries++ < MAX_RETRIES) {
|
||||
StatusUpdateListener listener = getListener();
|
||||
if (listener != null) {
|
||||
listener.update(getCommunicationStatus());
|
||||
}
|
||||
handler.getWebInterface().enqueueCommand(this);
|
||||
} else {
|
||||
String json = getContentAsString(StandardCharsets.UTF_8);
|
||||
if (json != null && !json.isEmpty()) {
|
||||
logger.debug("JSON String: {}", json);
|
||||
DataResponse jsonObject = fromJson(json);
|
||||
if (jsonObject != null) {
|
||||
handler.updateChannelStatus(transformer.transform(jsonObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.command;
|
||||
|
||||
import static org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.FormContentProvider;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.openhab.binding.nibeuplink.internal.callback.AbstractUplinkCommandCallback;
|
||||
import org.openhab.binding.nibeuplink.internal.connector.StatusUpdateListener;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.NibeUplinkHandler;
|
||||
|
||||
/**
|
||||
* implements the login to the webinterface
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Login extends AbstractUplinkCommandCallback implements NibeUplinkCommand {
|
||||
|
||||
public Login(NibeUplinkHandler handler, StatusUpdateListener listener) {
|
||||
super(handler.getConfiguration(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Request prepareRequest(Request requestToPrepare) {
|
||||
Fields fields = new Fields();
|
||||
fields.add(LOGIN_FIELD_EMAIL, config.getUser());
|
||||
fields.add(LOGIN_FIELD_PASSWORD, config.getPassword());
|
||||
fields.add(LOGIN_FIELD_RETURN_URL, "");
|
||||
FormContentProvider cp = new FormContentProvider(fields);
|
||||
|
||||
requestToPrepare.content(cp);
|
||||
requestToPrepare.followRedirects(false);
|
||||
requestToPrepare.method(HttpMethod.POST);
|
||||
|
||||
return requestToPrepare;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getURL() {
|
||||
return LOGIN_URL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@Nullable Result result) {
|
||||
StatusUpdateListener listener = getListener();
|
||||
if (listener != null) {
|
||||
listener.update(getCommunicationStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.command;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Response.CompleteListener;
|
||||
import org.eclipse.jetty.client.api.Response.ContentListener;
|
||||
import org.eclipse.jetty.client.api.Response.FailureListener;
|
||||
import org.eclipse.jetty.client.api.Response.SuccessListener;
|
||||
import org.openhab.binding.nibeuplink.internal.connector.StatusUpdateListener;
|
||||
|
||||
/**
|
||||
* public interface for all commands
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface NibeUplinkCommand extends SuccessListener, FailureListener, ContentListener, CompleteListener {
|
||||
|
||||
public static int MAX_RETRIES = 5;
|
||||
|
||||
/**
|
||||
* this method is to be called by the UplinkWebinterface class
|
||||
*
|
||||
* @param asyncclient client which will handle the command
|
||||
*/
|
||||
void performAction(HttpClient asyncclient);
|
||||
|
||||
/**
|
||||
* get the current listener
|
||||
*
|
||||
* @return instance of the listener, might be null.
|
||||
*/
|
||||
@Nullable
|
||||
StatusUpdateListener getListener();
|
||||
|
||||
/**
|
||||
* register a listener
|
||||
*
|
||||
* @param listener the listener to be registered.
|
||||
*/
|
||||
void setListener(StatusUpdateListener listener);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.command;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.FormContentProvider;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants;
|
||||
import org.openhab.binding.nibeuplink.internal.callback.AbstractUplinkCommandCallback;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.ChannelUtil;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.NibeUplinkHandler;
|
||||
import org.openhab.binding.nibeuplink.internal.model.ValidationException;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
import org.openhab.core.types.Command;
|
||||
|
||||
/**
|
||||
* allows update of writable channels
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class UpdateSetting extends AbstractUplinkCommandCallback implements NibeUplinkCommand {
|
||||
|
||||
private final NibeUplinkHandler handler;
|
||||
private final Channel channel;
|
||||
private String value;
|
||||
private int retries = 0;
|
||||
|
||||
public UpdateSetting(NibeUplinkHandler handler, Channel channel, Command command) {
|
||||
super(handler.getConfiguration());
|
||||
this.handler = handler;
|
||||
this.channel = channel;
|
||||
this.value = extractValue(command);
|
||||
}
|
||||
|
||||
private String extractValue(Command command) {
|
||||
// this is necessary because we must not send the unit to the nibe backend
|
||||
if (command instanceof QuantityType<?>) {
|
||||
return String.valueOf(((QuantityType<?>) command).doubleValue());
|
||||
} else if (command instanceof OnOffType) {
|
||||
return ChannelUtil.mapValue(channel, (OnOffType) command);
|
||||
} else {
|
||||
return command.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Request prepareRequest(Request requestToPrepare) {
|
||||
ChannelTypeUID typeUID = channel.getChannelTypeUID();
|
||||
String channelId = channel.getUID().getIdWithoutGroup();
|
||||
|
||||
if (typeUID == null || typeUID.getId() == null
|
||||
|| !typeUID.getId().startsWith(NibeUplinkBindingConstants.RW_CHANNEL_PREFIX)) {
|
||||
logger.info("channel '{}' does not support write access - value to set '{}'", channelId, value);
|
||||
throw new UnsupportedOperationException("channel (" + channelId + ") does not support write access");
|
||||
}
|
||||
|
||||
// although we have integers openhab often transfers decimals which will then cause a validation error. So we
|
||||
// will shorten here.
|
||||
if (value.endsWith(".0")) {
|
||||
value = value.substring(0, value.length() - 2);
|
||||
}
|
||||
|
||||
String expr = ChannelUtil.getValidationExpression(channel);
|
||||
|
||||
if (value.matches(expr)) {
|
||||
Fields fields = new Fields();
|
||||
fields.add(channelId, value);
|
||||
|
||||
FormContentProvider cp = new FormContentProvider(fields);
|
||||
|
||||
requestToPrepare.header(HttpHeader.ACCEPT_ENCODING, StandardCharsets.UTF_8.name());
|
||||
requestToPrepare.content(cp);
|
||||
requestToPrepare.followRedirects(false);
|
||||
requestToPrepare.method(HttpMethod.POST);
|
||||
|
||||
return requestToPrepare;
|
||||
} else {
|
||||
logger.info("channel '{}' does not allow value '{}' - validation rule '{}'", channelId, value, expr);
|
||||
throw new ValidationException("channel (" + channelId + ") could not be updated due to a validation error");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getURL() {
|
||||
return NibeUplinkBindingConstants.MANAGE_API_BASE_URL + config.getNibeId()
|
||||
+ ChannelUtil.getWriteApiUrlSuffix(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@Nullable Result result) {
|
||||
logger.debug("onComplete()");
|
||||
|
||||
if (!HttpStatus.Code.FOUND.equals(getCommunicationStatus().getHttpCode()) && retries++ < MAX_RETRIES) {
|
||||
logger.debug("Could not set value '{}' for channel '{}' ({})", value, channel.getUID().getId(),
|
||||
channel.getLabel());
|
||||
handler.getWebInterface().enqueueCommand(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.config;
|
||||
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Bean holding configuration data according to bridge.xml
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NibeUplinkConfiguration {
|
||||
|
||||
private @Nullable String user;
|
||||
private @Nullable String password;
|
||||
private @Nullable String nibeId;
|
||||
|
||||
private Integer asyncTimeout = 120;
|
||||
private Integer syncTimeout = 120;
|
||||
private Integer pollingInterval = 60;
|
||||
private Integer houseKeepingInterval = 3600;
|
||||
|
||||
public @Nullable String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public @Nullable String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public @Nullable String getNibeId() {
|
||||
return nibeId;
|
||||
}
|
||||
|
||||
public void setNibeId(String nibeId) {
|
||||
this.nibeId = nibeId;
|
||||
}
|
||||
|
||||
public Integer getAsyncTimeout() {
|
||||
return asyncTimeout;
|
||||
}
|
||||
|
||||
public void setAsyncTimeout(Integer asyncTimeout) {
|
||||
this.asyncTimeout = asyncTimeout;
|
||||
}
|
||||
|
||||
public Integer getSyncTimeout() {
|
||||
return syncTimeout;
|
||||
}
|
||||
|
||||
public void setSyncTimeout(Integer syncTimeout) {
|
||||
this.syncTimeout = syncTimeout;
|
||||
}
|
||||
|
||||
public Integer getPollingInterval() {
|
||||
return pollingInterval;
|
||||
}
|
||||
|
||||
public void setPollingInterval(Integer pollingInterval) {
|
||||
this.pollingInterval = pollingInterval;
|
||||
}
|
||||
|
||||
public Integer getHouseKeepingInterval() {
|
||||
return houseKeepingInterval;
|
||||
}
|
||||
|
||||
public void setHouseKeepingInterval(Integer houseKeepingInterval) {
|
||||
this.houseKeepingInterval = houseKeepingInterval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this).append("user", getUser()).append("password", getPassword())
|
||||
.append("nibeId", getNibeId()).append("pollingInterval", getPollingInterval())
|
||||
.append("houseKeepingInterval", getHouseKeepingInterval()).append("asyncTimeout", getAsyncTimeout())
|
||||
.append("syncTimeout", getSyncTimeout()).toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.connector;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.http.HttpStatus.Code;
|
||||
|
||||
/**
|
||||
* this class contains the HTTP status of the communication and an optional exception that might occoured during
|
||||
* communication
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class CommunicationStatus {
|
||||
|
||||
private @Nullable Code httpCode;
|
||||
private @Nullable Exception error;
|
||||
|
||||
public final Code getHttpCode() {
|
||||
Code code = httpCode;
|
||||
return code == null ? Code.INTERNAL_SERVER_ERROR : code;
|
||||
}
|
||||
|
||||
public final void setHttpCode(Code httpCode) {
|
||||
this.httpCode = httpCode;
|
||||
}
|
||||
|
||||
public final @Nullable Exception getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public final void setError(Exception error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public final String getMessage() {
|
||||
Exception err = error;
|
||||
String msg = getHttpCode().getMessage();
|
||||
if (err != null && err.getMessage() != null && !err.getMessage().isEmpty()) {
|
||||
return err.getMessage();
|
||||
} else if (msg != null && !msg.isEmpty()) {
|
||||
return msg;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.connector;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* callback interface to update the status of the {@link UplinkWebInterface}
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface StatusUpdateListener {
|
||||
|
||||
void update(CommunicationStatus status);
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.connector;
|
||||
|
||||
import static org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants.*;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.openhab.binding.nibeuplink.internal.AtomicReferenceTrait;
|
||||
import org.openhab.binding.nibeuplink.internal.command.Login;
|
||||
import org.openhab.binding.nibeuplink.internal.command.NibeUplinkCommand;
|
||||
import org.openhab.binding.nibeuplink.internal.config.NibeUplinkConfiguration;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.NibeUplinkHandler;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This class handles requests to the NibeUplink web interface. It manages authentication and wraps commands.
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class UplinkWebInterface implements AtomicReferenceTrait {
|
||||
|
||||
private static final int NIBE_ID_THRESHOLD = 14;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(UplinkWebInterface.class);
|
||||
|
||||
/**
|
||||
* Configuration
|
||||
*/
|
||||
private NibeUplinkConfiguration config;
|
||||
|
||||
/**
|
||||
* handler for updating thing status
|
||||
*/
|
||||
private final NibeUplinkHandler uplinkHandler;
|
||||
|
||||
/**
|
||||
* holds authentication status
|
||||
*/
|
||||
private boolean authenticated = false;
|
||||
|
||||
/**
|
||||
* HTTP client for asynchronous calls
|
||||
*/
|
||||
private final HttpClient httpClient;
|
||||
|
||||
/**
|
||||
* the scheduler which periodically sends web requests to the solaredge API. Should be initiated with the thing's
|
||||
* existing scheduler instance.
|
||||
*/
|
||||
private final ScheduledExecutorService scheduler;
|
||||
|
||||
/**
|
||||
* request executor
|
||||
*/
|
||||
private final WebRequestExecutor requestExecutor;
|
||||
|
||||
/**
|
||||
* periodic request executor job
|
||||
*/
|
||||
private AtomicReference<@Nullable Future<?>> requestExecutorJobReference = new AtomicReference<>(null);
|
||||
|
||||
/**
|
||||
* this class is responsible for executing periodic web requests. This ensures that only one request is executed at
|
||||
* the same time and there will be a guaranteed minimum delay between subsequent requests.
|
||||
*
|
||||
* @author afriese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
private class WebRequestExecutor implements Runnable {
|
||||
|
||||
/**
|
||||
* queue which holds the commands to execute
|
||||
*/
|
||||
private final Queue<@Nullable NibeUplinkCommand> commandQueue;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
WebRequestExecutor() {
|
||||
this.commandQueue = new BlockingArrayQueue<>(WEB_REQUEST_QUEUE_MAX_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* puts a command into the queue
|
||||
*
|
||||
* @param command the command which will be queued
|
||||
*/
|
||||
void enqueue(NibeUplinkCommand command) {
|
||||
try {
|
||||
commandQueue.add(command);
|
||||
} catch (IllegalStateException ex) {
|
||||
if (commandQueue.size() >= WEB_REQUEST_QUEUE_MAX_SIZE) {
|
||||
logger.debug(
|
||||
"Could not add command to command queue because queue is already full. Maybe NIBE Uplink is down?");
|
||||
} else {
|
||||
logger.warn("Could not add command to queue - IllegalStateException");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* executes the web request
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isAuthenticated()) {
|
||||
authenticate();
|
||||
}
|
||||
|
||||
else if (isAuthenticated() && !commandQueue.isEmpty()) {
|
||||
StatusUpdateListener statusUpdater = new StatusUpdateListener() {
|
||||
@Override
|
||||
public void update(CommunicationStatus status) {
|
||||
switch (status.getHttpCode()) {
|
||||
case SERVICE_UNAVAILABLE:
|
||||
uplinkHandler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
|
||||
status.getMessage());
|
||||
setAuthenticated(false);
|
||||
break;
|
||||
case FOUND:
|
||||
uplinkHandler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"most likely your NibeId is wrong. please check your NibeId.");
|
||||
setAuthenticated(false);
|
||||
break;
|
||||
case OK:
|
||||
// no action needed as the thing is already online.
|
||||
break;
|
||||
default:
|
||||
uplinkHandler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
status.getMessage());
|
||||
setAuthenticated(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NibeUplinkCommand command = commandQueue.poll();
|
||||
if (command != null) {
|
||||
command.setListener(statusUpdater);
|
||||
command.performAction(httpClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to set up interface
|
||||
*
|
||||
* @param config the Bridge configuration
|
||||
*/
|
||||
public UplinkWebInterface(ScheduledExecutorService scheduler, NibeUplinkHandler handler, HttpClient httpClient) {
|
||||
this.config = handler.getConfiguration();
|
||||
this.uplinkHandler = handler;
|
||||
this.scheduler = scheduler;
|
||||
this.requestExecutor = new WebRequestExecutor();
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* starts the periodic request executor job which handles all web requests
|
||||
*/
|
||||
public void start() {
|
||||
this.config = uplinkHandler.getConfiguration();
|
||||
setAuthenticated(false);
|
||||
updateJobReference(requestExecutorJobReference, scheduler.scheduleWithFixedDelay(requestExecutor,
|
||||
WEB_REQUEST_INITIAL_DELAY, WEB_REQUEST_INTERVAL, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
/**
|
||||
* queues any command for execution
|
||||
*
|
||||
* @param command the command which will be put into the queue
|
||||
*/
|
||||
public void enqueueCommand(NibeUplinkCommand command) {
|
||||
requestExecutor.enqueue(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* authenticates with the Nibe Uplink WEB interface
|
||||
*
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
private synchronized void authenticate() {
|
||||
setAuthenticated(false);
|
||||
|
||||
if (preCheck()) {
|
||||
StatusUpdateListener statusUpdater = new StatusUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void update(CommunicationStatus status) {
|
||||
switch (status.getHttpCode()) {
|
||||
case FOUND:
|
||||
uplinkHandler.setStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, "logged in");
|
||||
setAuthenticated(true);
|
||||
break;
|
||||
case OK:
|
||||
uplinkHandler.setStatusInfo(ThingStatus.UNKNOWN, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"invalid username or password");
|
||||
setAuthenticated(false);
|
||||
break;
|
||||
case SERVICE_UNAVAILABLE:
|
||||
uplinkHandler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
|
||||
status.getMessage());
|
||||
setAuthenticated(false);
|
||||
break;
|
||||
default:
|
||||
uplinkHandler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
status.getMessage());
|
||||
setAuthenticated(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
new Login(uplinkHandler, statusUpdater).performAction(httpClient);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* performs some pre cheks on configuration before attempting to login
|
||||
*
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
private boolean preCheck() {
|
||||
String preCheckStatusMessage = "";
|
||||
String localPassword = config.getPassword();
|
||||
String localUser = config.getUser();
|
||||
String localNibeId = config.getNibeId();
|
||||
|
||||
if (localPassword == null || localPassword.isEmpty()) {
|
||||
preCheckStatusMessage = "please configure password first";
|
||||
} else if (localUser == null || localUser.isEmpty()) {
|
||||
preCheckStatusMessage = "please configure user first";
|
||||
} else if (localNibeId == null || localNibeId.isEmpty()) {
|
||||
preCheckStatusMessage = "please configure nibeId first";
|
||||
} else if (localNibeId.length() > NIBE_ID_THRESHOLD) {
|
||||
preCheckStatusMessage = "your NibeId is too long. Please refer to the documentation on how to set this value.";
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.uplinkHandler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
preCheckStatusMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* will be called by the ThingHandler to abort periodic jobs.
|
||||
*/
|
||||
public void dispose() {
|
||||
logger.debug("Webinterface disposed.");
|
||||
cancelJobReference(requestExecutorJobReference);
|
||||
setAuthenticated(false);
|
||||
}
|
||||
|
||||
private boolean isAuthenticated() {
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
private void setAuthenticated(boolean authenticated) {
|
||||
this.authenticated = authenticated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.handler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.Channel;
|
||||
|
||||
/**
|
||||
* this interface provides all methods which deal with channels
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface ChannelProvider {
|
||||
|
||||
List<Channel> getChannels();
|
||||
|
||||
Set<Channel> getDeadChannels();
|
||||
|
||||
@Nullable
|
||||
Channel getSpecificChannel(String channelCode);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants;
|
||||
import org.openhab.binding.nibeuplink.internal.model.ConfigurationException;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* this class provides all methods which deal with channels
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public final class ChannelUtil {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ChannelUtil.class);
|
||||
|
||||
/**
|
||||
* only static methods no instance needed
|
||||
*/
|
||||
private ChannelUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether the channel ha a valid numeric Id
|
||||
*
|
||||
* @param channel to check
|
||||
* @return true or false
|
||||
*/
|
||||
public static boolean isValidNibeChannel(Channel channel) {
|
||||
String id = channel.getUID().getIdWithoutGroup();
|
||||
return id.matches(NibeUplinkBindingConstants.VALID_CHANNEL_ID_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* map data response from API to OnOff-Type. uses mapping from channel configuration
|
||||
*
|
||||
* @param channel switch channel which has mapping configured
|
||||
* @param value value to map
|
||||
* @return mapped value
|
||||
*/
|
||||
public static State mapValue(Channel channel, String value) {
|
||||
String off = getOffMapping(channel);
|
||||
String on = getOnMapping(channel);
|
||||
if (value.equals(off)) {
|
||||
return OnOffType.OFF;
|
||||
} else if (value.equals(on)) {
|
||||
return OnOffType.ON;
|
||||
} else {
|
||||
logger.warn("Channel {} value '{}' could not be mapped, valid values: ON={}, OFF={}",
|
||||
channel.getUID().getId(), value, on, off);
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* map data response from API to OnOff-Type. uses mapping from channel configuration
|
||||
*
|
||||
* @param channel switch channel which has mapping configured
|
||||
* @param value value to map
|
||||
* @return mapped value
|
||||
*/
|
||||
public static State mapValue(Channel channel, long value) {
|
||||
return mapValue(channel, String.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* map OnOff-Type to API compatible value. uses mapping from channel configuration
|
||||
*
|
||||
* @param channel switch channel which has mapping configured
|
||||
* @param value value to map
|
||||
* @return mapped value
|
||||
*/
|
||||
public static String mapValue(Channel channel, OnOffType value) {
|
||||
if (value.equals(OnOffType.OFF)) {
|
||||
return String.valueOf(getOffMapping(channel));
|
||||
} else {
|
||||
return String.valueOf(getOnMapping(channel));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves the validation expression which is assigned to this channel, fallback to a default, if no validation is
|
||||
* defined.
|
||||
*
|
||||
* @param channel
|
||||
* @return the validation expression
|
||||
*/
|
||||
public static String getValidationExpression(Channel channel) {
|
||||
String expr = getPropertyOrParameter(channel, NibeUplinkBindingConstants.PARAMETER_NAME_VALIDATION_REGEXP);
|
||||
if (expr == null) {
|
||||
logger.info("Channel {} does not have a validation expression configured", channel.getUID().getId());
|
||||
throw new ConfigurationException(
|
||||
"channel (" + channel.getUID().getId() + ") does not have a validation expression configured");
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves the write API url suffix which is assigned to this channel.
|
||||
*
|
||||
* @param channel
|
||||
* @return the url suffix
|
||||
*/
|
||||
public static String getWriteApiUrlSuffix(Channel channel) {
|
||||
String suffix = getPropertyOrParameter(channel, NibeUplinkBindingConstants.PARAMETER_NAME_WRITE_API_URL);
|
||||
if (suffix == null) {
|
||||
logger.info("channel {} does not have a write api url suffix configured", channel.getUID().getId());
|
||||
throw new ConfigurationException(
|
||||
"channel (" + channel.getUID().getId() + ") does not have a write api url suffix configured");
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
|
||||
private static @Nullable String getOffMapping(Channel channel) {
|
||||
return getPropertyOrParameter(channel, NibeUplinkBindingConstants.PARAMETER_NAME_OFF_MAPPING);
|
||||
}
|
||||
|
||||
private static @Nullable String getOnMapping(Channel channel) {
|
||||
return getPropertyOrParameter(channel, NibeUplinkBindingConstants.PARAMETER_NAME_ON_MAPPING);
|
||||
}
|
||||
|
||||
private static @Nullable String getPropertyOrParameter(Channel channel, String name) {
|
||||
String value = channel.getProperties().get(name);
|
||||
// also eclipse says this cannot be null, it definitely can!
|
||||
if (value == null || value.isEmpty()) {
|
||||
Object obj = channel.getConfiguration().get(name);
|
||||
value = obj == null ? null : obj.toString();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.handler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelGroupUID;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
/**
|
||||
* generic implementation of handler logic
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GenericHandler extends UplinkBaseHandler {
|
||||
|
||||
/**
|
||||
* constructor, called by the factory
|
||||
*
|
||||
* @param thing instance of the thing, passed in by the factory
|
||||
* @param httpClient the httpclient that communicates with the API
|
||||
*/
|
||||
public GenericHandler(Thing thing, HttpClient httpClient) {
|
||||
super(thing, httpClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Channel getSpecificChannel(String channelId) {
|
||||
Channel channel = getThing().getChannel(channelId);
|
||||
if (channel == null) {
|
||||
for (ChannelGroupUID channelGroupUID : getRegisteredGroups()) {
|
||||
channel = getThing().getChannel(new ChannelUID(channelGroupUID, channelId));
|
||||
if (channel != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Channel> getChannels() {
|
||||
return getThing().getChannels();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.handler;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.nibeuplink.internal.config.NibeUplinkConfiguration;
|
||||
import org.openhab.binding.nibeuplink.internal.connector.UplinkWebInterface;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* public interface of the {@link UplinkBaseHandler}
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface NibeUplinkHandler extends ThingHandler, ChannelProvider {
|
||||
/**
|
||||
* Called from {@link NibeUplinkWebInterface#authenticate()} to update
|
||||
* the thing status because updateStatus is protected.
|
||||
*
|
||||
* @param status Bridge status
|
||||
* @param statusDetail Bridge status detail
|
||||
* @param description Bridge status description
|
||||
*/
|
||||
void setStatusInfo(ThingStatus status, ThingStatusDetail statusDetail, String description);
|
||||
|
||||
/**
|
||||
* Provides the web interface object.
|
||||
*
|
||||
* @return The web interface object
|
||||
*/
|
||||
UplinkWebInterface getWebInterface();
|
||||
|
||||
void updateChannelStatus(Map<Channel, State> values);
|
||||
|
||||
NibeUplinkConfiguration getConfiguration();
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.handler;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.nibeuplink.internal.AtomicReferenceTrait;
|
||||
import org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants;
|
||||
import org.openhab.binding.nibeuplink.internal.command.UpdateSetting;
|
||||
import org.openhab.binding.nibeuplink.internal.config.NibeUplinkConfiguration;
|
||||
import org.openhab.binding.nibeuplink.internal.connector.UplinkWebInterface;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelGroupUID;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link UplinkBaseHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class UplinkBaseHandler extends BaseThingHandler implements NibeUplinkHandler, AtomicReferenceTrait {
|
||||
private final Logger logger = LoggerFactory.getLogger(UplinkBaseHandler.class);
|
||||
|
||||
private final long POLLING_INITIAL_DELAY = 30;
|
||||
private final long HOUSE_KEEPING_INITIAL_DELAY = 300;
|
||||
|
||||
private final Set<Channel> deadChannels = new HashSet<>(100);
|
||||
private final Set<ChannelGroupUID> registeredGroups = new HashSet<>(10);
|
||||
|
||||
/**
|
||||
* Interface object for querying the NibeUplink web interface
|
||||
*/
|
||||
private UplinkWebInterface webInterface;
|
||||
|
||||
/**
|
||||
* Schedule for polling
|
||||
*/
|
||||
private final AtomicReference<@Nullable Future<?>> pollingJobReference;
|
||||
|
||||
/**
|
||||
* Schedule for periodic cleaning dead channel list
|
||||
*/
|
||||
private final AtomicReference<@Nullable Future<?>> deadChannelHouseKeepingReference;
|
||||
|
||||
public UplinkBaseHandler(Thing thing, HttpClient httpClient) {
|
||||
super(thing);
|
||||
this.webInterface = new UplinkWebInterface(scheduler, this, httpClient);
|
||||
this.pollingJobReference = new AtomicReference<>(null);
|
||||
this.deadChannelHouseKeepingReference = new AtomicReference<>(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (!(command instanceof RefreshType)) {
|
||||
logger.debug("command for {}: {}", channelUID.getIdWithoutGroup(), command.toString());
|
||||
Channel channel = getSpecificChannel(channelUID.getIdWithoutGroup());
|
||||
if (channel != null) {
|
||||
ChannelTypeUID typeUID = channel.getChannelTypeUID();
|
||||
if (typeUID != null && typeUID.getId() != null
|
||||
&& typeUID.getId().startsWith(NibeUplinkBindingConstants.RW_CHANNEL_PREFIX)) {
|
||||
webInterface.enqueueCommand(new UpdateSetting(this, channel, command));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("About to initialize NibeUplink");
|
||||
NibeUplinkConfiguration config = getConfiguration();
|
||||
logger.debug("NibeUplink initialized with configuration: {}", config);
|
||||
|
||||
registeredGroups.clear();
|
||||
validateChannelsAndRegisterGroups();
|
||||
|
||||
startPolling();
|
||||
webInterface.start();
|
||||
updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "waiting for web api login");
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the channels out of the configuration
|
||||
*
|
||||
*/
|
||||
private void validateChannelsAndRegisterGroups() {
|
||||
logger.debug("Validating {} channels", getThing().getChannels().size());
|
||||
for (Channel channel : getThing().getChannels()) {
|
||||
if (!ChannelUtil.isValidNibeChannel(channel)) {
|
||||
logger.warn("Channel {} is not a valid Nibe channel ({})", channel.getUID().getIdWithoutGroup(),
|
||||
channel.getLabel());
|
||||
deadChannels.add(channel);
|
||||
} else {
|
||||
logger.debug("Successfully validated channel {} ({})", channel.getUID().getIdWithoutGroup(),
|
||||
channel.getLabel());
|
||||
String groupId = channel.getUID().getGroupId();
|
||||
if (groupId != null) {
|
||||
ThingUID thingUID = this.getThing().getUID();
|
||||
if (registeredGroups.add(new ChannelGroupUID(thingUID, groupId))) {
|
||||
logger.debug("Successfully registered channel-group '{}'", groupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the polling.
|
||||
*/
|
||||
private void startPolling() {
|
||||
updateJobReference(pollingJobReference, scheduler.scheduleWithFixedDelay(new UplinkPolling(this),
|
||||
POLLING_INITIAL_DELAY, getConfiguration().getPollingInterval(), TimeUnit.SECONDS));
|
||||
updateJobReference(deadChannelHouseKeepingReference, scheduler.scheduleWithFixedDelay(deadChannels::clear,
|
||||
HOUSE_KEEPING_INITIAL_DELAY, getConfiguration().getHouseKeepingInterval(), TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the bridge.
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Handler disposed.");
|
||||
|
||||
cancelJobReference(pollingJobReference);
|
||||
cancelJobReference(deadChannelHouseKeepingReference);
|
||||
|
||||
// the webinterface also makes use of the scheduler and must stop it's jobs
|
||||
webInterface.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UplinkWebInterface getWebInterface() {
|
||||
return webInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* will update all channels provided in the map
|
||||
*
|
||||
* @param values map containing the data updates
|
||||
*/
|
||||
@Override
|
||||
public void updateChannelStatus(Map<Channel, @Nullable State> values) {
|
||||
logger.debug("Handling channel update. ({} Channels)", values.size());
|
||||
|
||||
for (Channel channel : values.keySet()) {
|
||||
if (getChannels().contains(channel)) {
|
||||
State value = values.get(channel);
|
||||
if (value != null) {
|
||||
logger.debug("Channel is to be updated: {}: {}", channel.getUID().getAsString(), value);
|
||||
updateState(channel.getUID(), value);
|
||||
}
|
||||
} else {
|
||||
logger.debug("Could not identify channel: {} for model {}", channel.getUID().getAsString(),
|
||||
getThing().getThingTypeUID().getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Channel> getDeadChannels() {
|
||||
return deadChannels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatusInfo(ThingStatus status, ThingStatusDetail statusDetail, String description) {
|
||||
super.updateStatus(status, statusDetail, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NibeUplinkConfiguration getConfiguration() {
|
||||
return this.getConfigAs(NibeUplinkConfiguration.class);
|
||||
}
|
||||
|
||||
public Set<ChannelGroupUID> getRegisteredGroups() {
|
||||
return registeredGroups;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.nibeuplink.internal.command.GenericStatusUpdate;
|
||||
import org.openhab.binding.nibeuplink.internal.command.NibeUplinkCommand;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Polling worker class. This is responsible for periodic polling of status values.
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class UplinkPolling implements Runnable {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* Handler for delegation to callbacks.
|
||||
*/
|
||||
private final NibeUplinkHandler handler;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param handler instance of the thing handler
|
||||
*/
|
||||
public UplinkPolling(NibeUplinkHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll the Nibe Uplink webservice one time.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
logger.debug("polling NibeUplink {}", handler.getConfiguration());
|
||||
|
||||
NibeUplinkCommand command = new GenericStatusUpdate(handler);
|
||||
handler.getWebInterface().enqueueCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.model;
|
||||
|
||||
/**
|
||||
* used to determine the group a channel belongs to
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
public enum ChannelGroup {
|
||||
BASE,
|
||||
GENERAL,
|
||||
COMPRESSOR,
|
||||
HOTWATER,
|
||||
AIRSUPPLY,
|
||||
CUSTOM
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* exception whichs is used to state a validation error
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ConfigurationException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ConfigurationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ConfigurationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ConfigurationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ConfigurationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* common interface for all data response classes
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface DataResponse {
|
||||
Map<String, Long> getValues();
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.model;
|
||||
|
||||
import static org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.ChannelProvider;
|
||||
import org.openhab.binding.nibeuplink.internal.handler.ChannelUtil;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.MetricPrefix;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.SmartHomeUnits;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* transforms the http response into the openhab datamodel (instances of State)
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class DataResponseTransformer {
|
||||
private final Logger logger = LoggerFactory.getLogger(DataResponseTransformer.class);
|
||||
|
||||
private static final double UNSCALED = 1;
|
||||
private static final double DIV_10 = 0.1;
|
||||
private static final double DIV_100 = 0.01;
|
||||
|
||||
private final ChannelProvider channelProvider;
|
||||
|
||||
public DataResponseTransformer(ChannelProvider channelProvider) {
|
||||
this.channelProvider = channelProvider;
|
||||
}
|
||||
|
||||
public Map<Channel, State> transform(DataResponse response) {
|
||||
Map<String, Long> source = response.getValues();
|
||||
Map<Channel, State> result = new HashMap<>(source.size());
|
||||
|
||||
for (String channelId : source.keySet()) {
|
||||
Long value = source.get(channelId);
|
||||
|
||||
Channel channel = channelProvider.getSpecificChannel(channelId);
|
||||
if (channel == null) {
|
||||
// This should not happen but we want to get informed about it
|
||||
logger.warn("Channel not found: {}", channelId);
|
||||
} else {
|
||||
ChannelTypeUID typeUID = channel.getChannelTypeUID();
|
||||
String type = typeUID == null ? "null" : typeUID.getId();
|
||||
|
||||
switch (type) {
|
||||
case CHANNEL_TYPE_TEMPERATURE:
|
||||
case CHANNEL_TYPE_START_COOLING_RW:
|
||||
putQuantityType(result, channel, value, DIV_10, SIUnits.CELSIUS);
|
||||
break;
|
||||
case CHANNEL_TYPE_PRESSURE:
|
||||
putQuantityType(result, channel, value, DIV_10, SmartHomeUnits.BAR);
|
||||
break;
|
||||
case CHANNEL_TYPE_ENERGY:
|
||||
putQuantityType(result, channel, value, DIV_10, MetricPrefix.KILO(SmartHomeUnits.WATT_HOUR));
|
||||
break;
|
||||
case CHANNEL_TYPE_POWER:
|
||||
putQuantityType(result, channel, value, DIV_100, MetricPrefix.KILO(SmartHomeUnits.WATT));
|
||||
break;
|
||||
case CHANNEL_TYPE_SWITCH_RW:
|
||||
case CHANNEL_TYPE_SWITCH:
|
||||
putOnOffType(result, channel, value);
|
||||
break;
|
||||
case CHANNEL_TYPE_ELECTRIC_CURRENT:
|
||||
putQuantityType(result, channel, value, DIV_10, SmartHomeUnits.AMPERE);
|
||||
break;
|
||||
case CHANNEL_TYPE_TIME_UNSCALED:
|
||||
putQuantityType(result, channel, value, UNSCALED, SmartHomeUnits.HOUR);
|
||||
break;
|
||||
case CHANNEL_TYPE_TIME_SCALE10:
|
||||
putQuantityType(result, channel, value, DIV_10, SmartHomeUnits.HOUR);
|
||||
break;
|
||||
case CHANNEL_TYPE_FREQUENCY_UNSCALED:
|
||||
putQuantityType(result, channel, value, UNSCALED, SmartHomeUnits.HERTZ);
|
||||
break;
|
||||
case CHANNEL_TYPE_FREQUENCY_SCALE10:
|
||||
putQuantityType(result, channel, value, DIV_10, SmartHomeUnits.HERTZ);
|
||||
break;
|
||||
case CHANNEL_TYPE_FLOW:
|
||||
putQuantityType(result, channel, value, DIV_10,
|
||||
SmartHomeUnits.LITRE.divide(SmartHomeUnits.MINUTE));
|
||||
break;
|
||||
case CHANNEL_TYPE_SPEED:
|
||||
putQuantityType(result, channel, value, UNSCALED, SmartHomeUnits.PERCENT);
|
||||
break;
|
||||
case CHANNEL_TYPE_NUMBER_SCALE100:
|
||||
putDecimalType(result, channel, value, DIV_100);
|
||||
break;
|
||||
case CHANNEL_TYPE_NUMBER_SCALE10:
|
||||
case CHANNEL_TYPE_DEGREE_MINUTES_RW:
|
||||
case CHANNEL_TYPE_STOP_HEATING_RW:
|
||||
case CHANNEL_TYPE_STOP_ADD_HEATING_RW:
|
||||
case CHANNEL_TYPE_ROOM_SENSOR_FACTOR_RW:
|
||||
putDecimalType(result, channel, value, DIV_10);
|
||||
break;
|
||||
case CHANNEL_TYPE_NUMBER_UNSCALED:
|
||||
case CHANNEL_TYPE_DEFROSTING_STATE:
|
||||
case CHANNEL_TYPE_HPAC_STATE:
|
||||
case CHANNEL_TYPE_HW_LUX_RW:
|
||||
case CHANNEL_TYPE_HW_MODE_RW:
|
||||
case CHANNEL_TYPE_FAN_SPEED_RW:
|
||||
case CHANNEL_TYPE_FILTER_TIME_RW:
|
||||
case CHANNEL_TYPE_HEAT_OFFSET_RW:
|
||||
putDecimalType(result, channel, value, UNSCALED);
|
||||
break;
|
||||
default:
|
||||
logger.warn("could not handle unknown type {}, channel {}, value {}", type, channel.getUID(),
|
||||
value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private final void putQuantityType(Map<Channel, State> targetMap, Channel channel, long value, double factor,
|
||||
Unit<?> unit) {
|
||||
// make sure that values are stored as long if no factor is to be applied
|
||||
State val = factor == UNSCALED ? new QuantityType<>(value, unit) : new QuantityType<>(value * factor, unit);
|
||||
targetMap.put(channel, val);
|
||||
logger.debug("Channel {} transformed to QuantityType ({}*{} {}) -> {}", channel.getUID().getId(), value, factor,
|
||||
unit, val);
|
||||
}
|
||||
|
||||
private final void putOnOffType(Map<Channel, State> targetMap, Channel channel, long value) {
|
||||
State val = ChannelUtil.mapValue(channel, value);
|
||||
targetMap.put(channel, val);
|
||||
logger.debug("Channel {} transformed to OnOffType ({}) -> {}", channel.getUID().getId(), value, val);
|
||||
}
|
||||
|
||||
private final void putDecimalType(Map<Channel, State> targetMap, Channel channel, long value, double factor) {
|
||||
// make sure that values are stored as long if no factor is to be applied
|
||||
State val = factor == UNSCALED ? new DecimalType(value) : new DecimalType(value * factor);
|
||||
targetMap.put(channel, val);
|
||||
logger.debug("Channel {} transformed to DecimalType ({}*{}) -> {}", channel.getUID().getId(), value, factor,
|
||||
val);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* data class to map the json status response
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GenericDataResponse implements DataResponse {
|
||||
private final Logger logger = LoggerFactory.getLogger(GenericDataResponse.class);
|
||||
|
||||
@NonNullByDefault
|
||||
public static class Value {
|
||||
@SerializedName("VariableId")
|
||||
private @Nullable String variableId;
|
||||
@SerializedName("CurrentValue")
|
||||
private @Nullable String currentValue;
|
||||
@SerializedName("CurrentIntValue")
|
||||
private @Nullable Long currentIntValue;
|
||||
@SerializedName("IsLoading")
|
||||
private boolean isLoading;
|
||||
}
|
||||
|
||||
@SerializedName("IsOffline")
|
||||
private @Nullable String isOffline;
|
||||
@SerializedName("OnlineImage")
|
||||
private @Nullable String onlineImage;
|
||||
@SerializedName("Date")
|
||||
private @Nullable String date;
|
||||
@SerializedName("FuzzyDate")
|
||||
private @Nullable String fuzzyDate;
|
||||
@SerializedName("Values")
|
||||
private List<Value> values = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public Map<String, @Nullable Long> getValues() {
|
||||
Map<String, @Nullable Long> valueMap = new HashMap<>();
|
||||
for (Value value : values) {
|
||||
String id = value.variableId;
|
||||
if (!value.isLoading && id != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Channel {} updated to: {} ({})", value.variableId, value.currentIntValue,
|
||||
value.currentValue);
|
||||
}
|
||||
valueMap.put(id, value.currentIntValue);
|
||||
}
|
||||
}
|
||||
return valueMap;
|
||||
}
|
||||
|
||||
public @Nullable String getIsOffline() {
|
||||
return isOffline;
|
||||
}
|
||||
|
||||
public @Nullable String getOnlineImage() {
|
||||
return onlineImage;
|
||||
}
|
||||
|
||||
public @Nullable String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public @Nullable String getFuzzyDate() {
|
||||
return fuzzyDate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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.nibeuplink.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* exception whichs is used to state a validation error
|
||||
*
|
||||
* @author Alexander Friese - initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ValidationException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ValidationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ValidationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ValidationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ValidationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="nibeuplink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>NibeUplink Binding</name>
|
||||
<description>This is the binding for NibeUplink.</description>
|
||||
<author>Alexander Friese</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config-description:config-descriptions
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
|
||||
|
||||
<config-description uri="thing-type:nibeuplink:web">
|
||||
<parameter-group name="authentication">
|
||||
<label>Authentication</label>
|
||||
<description>Authentication settings.</description>
|
||||
</parameter-group>
|
||||
<parameter-group name="connection">
|
||||
<label>Connection</label>
|
||||
<description>Connection settings.</description>
|
||||
</parameter-group>
|
||||
<parameter-group name="general">
|
||||
<label>General</label>
|
||||
<description>General settings.</description>
|
||||
</parameter-group>
|
||||
<parameter-group name="customChannels">
|
||||
<label>Custom Channels</label>
|
||||
<description>Custom Channel configuration</description>
|
||||
</parameter-group>
|
||||
|
||||
<parameter name="user" type="text" required="true" groupName="authentication">
|
||||
<label>Username</label>
|
||||
<description>The Username to login at NibeIplink.</description>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="true" groupName="authentication">
|
||||
<label>Password</label>
|
||||
<context>password</context>
|
||||
<description>The Password to login at NibeIplink.</description>
|
||||
</parameter>
|
||||
<parameter name="nibeId" type="text" required="true" groupName="general">
|
||||
<label>Nibe ID</label>
|
||||
<description>The ID to identify the heat pump at NibeIplink.</description>
|
||||
</parameter>
|
||||
<parameter name="pollingInterval" type="integer" required="false" min="30" max="3600" unit="s"
|
||||
groupName="connection">
|
||||
<label>Polling Interval</label>
|
||||
<description>Interval in which data is polled from Nibe Uplink (in seconds).</description>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</config-description:config-descriptions>
|
||||
@@ -0,0 +1,26 @@
|
||||
# binding
|
||||
binding.nibeuplink.name = Nibe Uplink binding
|
||||
binding.nibeuplink.description = Abfrage von Nibe Wärmepumpendaten über die Nibe Uplink API.
|
||||
|
||||
# thing types
|
||||
thing-type.nibeuplink.web.label = Nibe Wärmepumpe
|
||||
thing-type.nibeuplink.web.description = Wärmepumpenspezifischer WebZugang zu Nibe Uplink
|
||||
|
||||
# groups
|
||||
thing-type.config.nibeuplink.web.group.authentication.label = Authentifizierung
|
||||
thing-type.config.nibeuplink.web.group.authentication.description = Einstellungen für die Authentifizierung.
|
||||
thing-type.config.nibeuplink.web.group.connection.label = Verbindung
|
||||
thing-type.config.nibeuplink.web.group.connection.description = Einstellungen für die Verbindung.
|
||||
thing-type.config.nibeuplink.web.group.general.label = Allgemeines
|
||||
thing-type.config.nibeuplink.web.group.general.description = Allgemeine Einstellungen.
|
||||
thing-type.config.nibeuplink.web.group.customChannels.label = Benutzerdefinierte Kanäle
|
||||
thing-type.config.nibeuplink.web.group.customChannels.description = Benutzerdefinierte Kanäle.
|
||||
|
||||
thing-type.config.nibeuplink.web.user.label = Benutzer
|
||||
thing-type.config.nibeuplink.web.user.description = Benutzer zur Authentifizierung bei Nibe Uplink.
|
||||
thing-type.config.nibeuplink.web.password.label = Passwort
|
||||
thing-type.config.nibeuplink.web.password.description = Passwort zur Authentifizierung bei Nibe Uplink.
|
||||
thing-type.config.nibeuplink.web.nibeId.label = Nibe ID
|
||||
thing-type.config.nibeuplink.web.nibeId.description = ID der Wärmepumpeninstallation bei Nibe Uplink.
|
||||
thing-type.config.nibeuplink.web.pollingInterval.label = Abfrageintervall
|
||||
thing-type.config.nibeuplink.web.pollingInterval.description = Intervall in welchem Abfragen an Nibe Uplink geschickt werden.
|
||||
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-group-type id="base-base">
|
||||
<label>Base Channels</label>
|
||||
<channels>
|
||||
<channel id="40004" typeId="type-temperature">
|
||||
<label>BT1 Outdoor Temperature</label>
|
||||
<description>Current outdoor temperature</description>
|
||||
</channel>
|
||||
<channel id="40067" typeId="type-temperature">
|
||||
<label>BT1 Average</label>
|
||||
<description>EB100-BT1 Outdoor temperature average</description>
|
||||
</channel>
|
||||
<channel id="43005" typeId="rwtype-degree-minutes">
|
||||
<label>Degree Minutes (16 Bit)</label>
|
||||
<description>Degree minutes, 16bit value (-32768 < x < 32767). Values outside valid values are rounded to the
|
||||
closest valid value.</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/4.9.3</property>
|
||||
<property name="validationExpression">-?[0-9]+</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="43009" typeId="type-temperature">
|
||||
<label>Calc. Supply S1</label>
|
||||
<description>Calculated supply temperature for the climate system</description>
|
||||
</channel>
|
||||
<channel id="40071" typeId="type-temperature">
|
||||
<label>BT25 Ext. Supply</label>
|
||||
<description>External supply temperature, BT25</description>
|
||||
</channel>
|
||||
<channel id="40033" typeId="type-temperature">
|
||||
<label>BT50 Room Temp S1</label>
|
||||
<description>Room Temperature S1 (BT50)</description>
|
||||
</channel>
|
||||
<channel id="43161" typeId="type-switch">
|
||||
<label>External Adjustment Activated Via Input S1</label>
|
||||
<description>External Adjustment Activated Via Input S1</description>
|
||||
<properties>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="40008" typeId="type-temperature">
|
||||
<label>BT2 Supply Temp S1</label>
|
||||
<description>Supply temperature for system 1</description>
|
||||
</channel>
|
||||
<channel id="40012" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT3 Return Temp</label>
|
||||
<description>Return temperature</description>
|
||||
</channel>
|
||||
<channel id="40072" typeId="type-flow">
|
||||
<label>BF1 EP14 Flow</label>
|
||||
<description>Current flow EP14|Current flow EP15</description>
|
||||
</channel>
|
||||
<channel id="40079" typeId="type-electric-current">
|
||||
<label>EB100-BE3 Current</label>
|
||||
<description>BE3 Current</description>
|
||||
</channel>
|
||||
<channel id="40081" typeId="type-electric-current">
|
||||
<label>EB100-BE2 Current</label>
|
||||
<description>BE2 Current</description>
|
||||
</channel>
|
||||
<channel id="40083" typeId="type-electric-current">
|
||||
<label>EB100-BE1 Current</label>
|
||||
<description>BE1 Current</description>
|
||||
</channel>
|
||||
<channel id="10033" typeId="type-switch">
|
||||
<label>Int. El.add. Blocked</label>
|
||||
<description>states if internal electric additional heater is blocked</description>
|
||||
<properties>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="43081" typeId="type-time-scale10">
|
||||
<label>Tot. Op.time Add.</label>
|
||||
<description>Total electric additive operation time</description>
|
||||
</channel>
|
||||
<channel id="43084" typeId="type-power">
|
||||
<label>Int. El.add. Power</label>
|
||||
<description>Current power from the internal electrical addition</description>
|
||||
</channel>
|
||||
<channel id="47212" typeId="type-power">
|
||||
<label>Max Int Add. Power</label>
|
||||
<description>Maximum power from the internal electrical addition</description>
|
||||
</channel>
|
||||
<channel id="48914" typeId="type-power">
|
||||
<label>Max Int Add. Power, SG Ready</label>
|
||||
<description>Maximum power from the internal electrical addition in SG-Ready Mode</description>
|
||||
</channel>
|
||||
<channel id="44308" typeId="type-energy">
|
||||
<label>Heat Meter - Heat Cpr EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="44304" typeId="type-energy">
|
||||
<label>Heat Meter - Pool Cpr EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="44300" typeId="type-energy">
|
||||
<label>Heat Meter - Heat Cpr and Add EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="48043" typeId="rwtype-switch">
|
||||
<label>Holiday</label>
|
||||
<description>states if Holiday mode is activated</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/4.7</property>
|
||||
<property name="validationExpression">.*</property>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">10</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="10012" typeId="type-switch">
|
||||
<label>Compressor Blocked</label>
|
||||
<description>states if the compressor is blocked</description>
|
||||
<properties>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="43437" typeId="type-speed-percent">
|
||||
<label>Supply Pump Speed EP14</label>
|
||||
<description>Supply Pump Speed, EP14 (GP6)</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="base-hotwater">
|
||||
<label>Hot Water Channels</label>
|
||||
<channels>
|
||||
<channel id="40013" typeId="type-temperature">
|
||||
<label>BT7 HW Top</label>
|
||||
<description>Hot water top temperature, BT7</description>
|
||||
</channel>
|
||||
<channel id="40014" typeId="type-temperature">
|
||||
<label>BT6 HW Load</label>
|
||||
<description>Hot water load temperature, BT6</description>
|
||||
</channel>
|
||||
<channel id="44306" typeId="type-energy">
|
||||
<label>Heat Meter - HW Cpr EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="44298" typeId="type-energy">
|
||||
<label>Heat Meter - HW Cpr and Add EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="48132" typeId="rwtype-hw-lux">
|
||||
<label>Temporary Lux</label>
|
||||
<description>Temporary hot water lux mode</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/2.1</property>
|
||||
<property name="validationExpression">[01234]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47041" typeId="rwtype-hw-mode">
|
||||
<label>Hot Water Mode</label>
|
||||
<description>The currently active hotwater mode</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/2.2</property>
|
||||
<property name="validationExpression">[012]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47045" typeId="type-temperature">
|
||||
<label>Start Temperature HW Economy</label>
|
||||
<description>Start temperature for heating water in Economy mode</description>
|
||||
</channel>
|
||||
<channel id="47049" typeId="type-temperature">
|
||||
<label>Stop Temperature HW Economy</label>
|
||||
<description>Stop temperature for heating water in Economy mode</description>
|
||||
</channel>
|
||||
<channel id="47044" typeId="type-temperature">
|
||||
<label>Start Temperature HW Normal</label>
|
||||
<description>Start temperature for heating water in Normal mode</description>
|
||||
</channel>
|
||||
<channel id="47048" typeId="type-temperature">
|
||||
<label>Stop Temperature HW Normal</label>
|
||||
<description>Stop temperature for heating water in Normal mode</description>
|
||||
</channel>
|
||||
<channel id="47043" typeId="type-temperature">
|
||||
<label>Start Temperature HW Luxury</label>
|
||||
<description>Start temperature for heating water in Luxury mode</description>
|
||||
</channel>
|
||||
<channel id="47047" typeId="type-temperature">
|
||||
<label>Stop Temperature HW Luxury</label>
|
||||
<description>Stop temperature for heating water in Luxory mode</description>
|
||||
</channel>
|
||||
<channel id="47046" typeId="type-temperature">
|
||||
<label>Stop Temperature Periodic HW</label>
|
||||
<description>Stop temperature for heating water in periodic heating</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-group-type id="f1145-general">
|
||||
<label>General Channels</label>
|
||||
<channels>
|
||||
<channel id="44302" typeId="type-energy">
|
||||
<label>Heat Meter - Cooling Cpr EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="44270" typeId="type-temperature">
|
||||
<label>Calculated Cooling Supply Temperature S1</label>
|
||||
<description>Calculated supply temperature in cooling mode for the climate system</description>
|
||||
</channel>
|
||||
<channel id="43103" typeId="type-hpac-state">
|
||||
<label>HPAC State</label>
|
||||
<description>State of the HPAC accessory</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="f1145-compressor">
|
||||
<label>Compressor Channels</label>
|
||||
<channels>
|
||||
<channel id="43424" typeId="type-defrosting-state">
|
||||
<label>Tot. HW Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time in hot water mode</description>
|
||||
</channel>
|
||||
<channel id="43420" typeId="type-defrosting-state">
|
||||
<label>Tot. Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time</description>
|
||||
</channel>
|
||||
<channel id="43416" typeId="type-number-unscaled">
|
||||
<label>Compressor Starts EB100-EP14</label>
|
||||
<description>Number of compressor starts</description>
|
||||
</channel>
|
||||
<channel id="40022" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT17 Suction</label>
|
||||
<description>Suction temperature, BT17</description>
|
||||
</channel>
|
||||
<channel id="40019" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT15 Liquid Line</label>
|
||||
<description>Liquid line temperature, BT15</description>
|
||||
</channel>
|
||||
<channel id="40018" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT14 Hot Gas Temp</label>
|
||||
<description>Hot gas temperature, BT14</description>
|
||||
</channel>
|
||||
<channel id="40017" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT12 Condensor Out</label>
|
||||
<description>Condensor out temperature, BT12</description>
|
||||
</channel>
|
||||
<channel id="40015" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT10 Brine in Temperature</label>
|
||||
<description>Brine in temperature, BT10</description>
|
||||
</channel>
|
||||
<channel id="40016" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT11 Brine out Temperature</label>
|
||||
<description>Brine out temperature, BT11</description>
|
||||
</channel>
|
||||
<channel id="43439" typeId="type-speed-percent">
|
||||
<label>EP14-GP2 Brine Pump Speed</label>
|
||||
<description>Brine pump speed EP14 (GP2)</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="f1145-airsupply">
|
||||
<label>Air Supply/Exhaust Channels</label>
|
||||
<channels>
|
||||
<channel id="40025" typeId="type-temperature">
|
||||
<label>BT20 Exhaust Air Temp. 1</label>
|
||||
<description>Exhaust Air Temperature (BT20)</description>
|
||||
</channel>
|
||||
<channel id="40026" typeId="type-temperature">
|
||||
<label>BT21 Vented Air Temp. 1</label>
|
||||
<description>Vented Air Temperature (BT21)</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="f1145" extensible="type-number-unscaled,type-number-scale10,type-number-scale100">
|
||||
<label>Nibe F1145</label>
|
||||
<description>Nibe F1145 heat pump connected through Nibe UpLink</description>
|
||||
<channel-groups>
|
||||
<channel-group typeId="base-base" id="base"/>
|
||||
<channel-group typeId="base-hotwater" id="hotwater"/>
|
||||
<channel-group typeId="f1145-general" id="general"/>
|
||||
<channel-group typeId="f1145-compressor" id="compressor"/>
|
||||
<channel-group typeId="f1145-airsupply" id="airsupply"/>
|
||||
</channel-groups>
|
||||
<config-description-ref uri="thing-type:nibeuplink:web"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-group-type id="f1155-general">
|
||||
<label>General Channels</label>
|
||||
<channels>
|
||||
<channel id="44302" typeId="type-energy">
|
||||
<label>Heat Meter - Cooling Cpr EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="f1155-compressor">
|
||||
<label>Compressor Channels</label>
|
||||
<channels>
|
||||
<channel id="43424" typeId="type-defrosting-state">
|
||||
<label>Tot. HW Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time in hot water mode</description>
|
||||
</channel>
|
||||
<channel id="43420" typeId="type-defrosting-state">
|
||||
<label>Tot. Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time</description>
|
||||
</channel>
|
||||
<channel id="43416" typeId="type-number-unscaled">
|
||||
<label>Compressor Starts EB100-EP14</label>
|
||||
<description>Number of compressor starts</description>
|
||||
</channel>
|
||||
<channel id="40022" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT17 Suction</label>
|
||||
<description>Suction temperature, BT17</description>
|
||||
</channel>
|
||||
<channel id="40019" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT15 Liquid Line</label>
|
||||
<description>Liquid line temperature, BT15</description>
|
||||
</channel>
|
||||
<channel id="40018" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT14 Hot Gas Temp</label>
|
||||
<description>Hot gas temperature, BT14</description>
|
||||
</channel>
|
||||
<channel id="40017" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT12 Condensor Out</label>
|
||||
<description>Condensor out temperature, BT12</description>
|
||||
</channel>
|
||||
<channel id="43136" typeId="type-frequency-scale10">
|
||||
<label>Compressor Frequency, Actual</label>
|
||||
<description>The compressor frequency the compressor is currently running at</description>
|
||||
</channel>
|
||||
<channel id="43122" typeId="type-frequency-unscaled">
|
||||
<label>Compr. Current Min.freq.</label>
|
||||
<description>The current minimum frequency of the compressor</description>
|
||||
</channel>
|
||||
<channel id="43123" typeId="type-frequency-unscaled">
|
||||
<label>Compr. Current Max.freq.</label>
|
||||
<description>The current maximum frequency of the compressor</description>
|
||||
</channel>
|
||||
<channel id="40015" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT10 Brine in Temperature</label>
|
||||
<description>Brine in temperature, BT10</description>
|
||||
</channel>
|
||||
<channel id="40016" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT11 Brine out Temperature</label>
|
||||
<description>Brine out temperature, BT11</description>
|
||||
</channel>
|
||||
<channel id="43439" typeId="type-speed-percent">
|
||||
<label>EP14-GP2 Brine Pump Speed</label>
|
||||
<description>Brine pump speed EP14 (GP2)</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="f1155-airsupply">
|
||||
<label>Air Supply/Exhaust Channels</label>
|
||||
<channels>
|
||||
<channel id="40025" typeId="type-temperature">
|
||||
<label>BT20 Exhaust Air Temp. 1</label>
|
||||
<description>Exhaust Air Temperature (BT20)</description>
|
||||
</channel>
|
||||
<channel id="40026" typeId="type-temperature">
|
||||
<label>BT21 Vented Air Temp. 1</label>
|
||||
<description>Vented Air Temperature (BT21)</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="f1155" extensible="type-number-unscaled,type-number-scale10,type-number-scale100">
|
||||
<label>Nibe F1155</label>
|
||||
<description>Nibe F1155 heat pump connected through Nibe UpLink</description>
|
||||
<channel-groups>
|
||||
<channel-group typeId="base-base" id="base"/>
|
||||
<channel-group typeId="base-hotwater" id="hotwater"/>
|
||||
<channel-group typeId="f1155-general" id="general"/>
|
||||
<channel-group typeId="f1155-compressor" id="compressor"/>
|
||||
<channel-group typeId="f1155-airsupply" id="airsupply"/>
|
||||
</channel-groups>
|
||||
<config-description-ref uri="thing-type:nibeuplink:web"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-group-type id="f730-compressor">
|
||||
<label>Compressor Channels</label>
|
||||
<channels>
|
||||
<channel id="43181" typeId="type-speed-percent">
|
||||
<label>Chargepump Speed</label>
|
||||
<description>Chargepump Speed</description>
|
||||
</channel>
|
||||
<channel id="43424" typeId="type-time-unscaled">
|
||||
<label>Tot. HW Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time in hot water mode</description>
|
||||
</channel>
|
||||
<channel id="43420" typeId="type-time-unscaled">
|
||||
<label>Tot. Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time</description>
|
||||
</channel>
|
||||
<channel id="43416" typeId="type-number-unscaled">
|
||||
<label>Compressor Starts EB100-EP14</label>
|
||||
<description>Number of compressor starts</description>
|
||||
</channel>
|
||||
<channel id="40022" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT17 Suction</label>
|
||||
<description>Suction temperature, BT17</description>
|
||||
</channel>
|
||||
<channel id="40019" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT15 Liquid Line</label>
|
||||
<description>Liquid line temperature, BT15</description>
|
||||
</channel>
|
||||
<channel id="40018" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT14 Hot Gas Temp</label>
|
||||
<description>Hot gas temperature, BT14</description>
|
||||
</channel>
|
||||
<channel id="40017" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT12 Condensor Out</label>
|
||||
<description>Condensor out temperature, BT12</description>
|
||||
</channel>
|
||||
<channel id="40020" typeId="type-temperature">
|
||||
<label>EB100-BT16 Evaporator Temp</label>
|
||||
<description>Evaporator Temp (BT16)</description>
|
||||
</channel>
|
||||
<channel id="43136" typeId="type-frequency-scale10">
|
||||
<label>Compressor Frequency, Actual</label>
|
||||
<description>The compressor frequency the compressor is currently running at</description>
|
||||
</channel>
|
||||
<channel id="43122" typeId="type-frequency-unscaled">
|
||||
<label>Compr. Current Min.freq.</label>
|
||||
<description>The current minimum frequency of the compressor</description>
|
||||
</channel>
|
||||
<channel id="43123" typeId="type-frequency-unscaled">
|
||||
<label>Compr. Current Max.freq.</label>
|
||||
<description>The current maximum frequency of the compressor</description>
|
||||
</channel>
|
||||
<channel id="43066" typeId="type-time-unscaled">
|
||||
<label>Defrosting Time</label>
|
||||
<description>Defrosting time, no defrosting heater in the product</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="f730-airsupply">
|
||||
<label>Air Supply/Exhaust Channels</label>
|
||||
<channels>
|
||||
<channel id="10001" typeId="type-speed-percent">
|
||||
<label>Fan Speed Current</label>
|
||||
<description>The current fan speed</description>
|
||||
</channel>
|
||||
<channel id="40025" typeId="type-temperature">
|
||||
<label>BT20 Exhaust Air Temp. 1</label>
|
||||
<description>Exhaust Air Temperature (BT20)</description>
|
||||
</channel>
|
||||
<channel id="40026" typeId="type-temperature">
|
||||
<label>BT21 Vented Air Temp. 1</label>
|
||||
<description>Vented Air Temperature (BT21)</description>
|
||||
</channel>
|
||||
<channel id="43124" typeId="type-number-scale10">
|
||||
<label>Airflow Ref.</label>
|
||||
<description>Reference value for the airflow.</description>
|
||||
</channel>
|
||||
<channel id="41026" typeId="type-number-unscaled">
|
||||
<label>EB100-Adjusted BS1 Air Flow</label>
|
||||
<description>Adjusted BS1 Air Flow (BT100)</description>
|
||||
</channel>
|
||||
<channel id="43125" typeId="type-number-unscaled">
|
||||
<label>Airflow Reduction</label>
|
||||
<description>Airflow Reduction</description>
|
||||
</channel>
|
||||
<channel id="40919" typeId="type-number-unscaled">
|
||||
<label>Air Mix</label>
|
||||
<description>Air Mix</description>
|
||||
</channel>
|
||||
<channel id="40101" typeId="type-temperature">
|
||||
<label>BT28 Airmix Temp</label>
|
||||
<description>External airmix temperature BT28</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="f730" extensible="type-number-unscaled,type-number-scale10,type-number-scale100">
|
||||
<label>Nibe F730</label>
|
||||
<description>Nibe F730 heat pump connected through Nibe UpLink</description>
|
||||
<channel-groups>
|
||||
<channel-group typeId="base-base" id="base"/>
|
||||
<channel-group typeId="base-hotwater" id="hotwater"/>
|
||||
<channel-group typeId="f730-compressor" id="compressor"/>
|
||||
<channel-group typeId="f730-airsupply" id="airsupply"/>
|
||||
</channel-groups>
|
||||
<config-description-ref uri="thing-type:nibeuplink:web"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-group-type id="f750-compressor">
|
||||
<label>Compressor Channels</label>
|
||||
<channels>
|
||||
<channel id="43181" typeId="type-speed-percent">
|
||||
<label>Chargepump Speed</label>
|
||||
<description>Chargepump Speed</description>
|
||||
</channel>
|
||||
<channel id="43424" typeId="type-time-unscaled">
|
||||
<label>Tot. HW Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time in hot water mode</description>
|
||||
</channel>
|
||||
<channel id="43420" typeId="type-time-unscaled">
|
||||
<label>Tot. Op.time Compr. EB100-EP14</label>
|
||||
<description>Total compressor operation time</description>
|
||||
</channel>
|
||||
<channel id="43416" typeId="type-number-unscaled">
|
||||
<label>Compressor Starts EB100-EP14</label>
|
||||
<description>Number of compressor starts</description>
|
||||
</channel>
|
||||
<channel id="40022" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT17 Suction</label>
|
||||
<description>Suction temperature, BT17</description>
|
||||
</channel>
|
||||
<channel id="40019" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT15 Liquid Line</label>
|
||||
<description>Liquid line temperature, BT15</description>
|
||||
</channel>
|
||||
<channel id="40018" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT14 Hot Gas Temp</label>
|
||||
<description>Hot gas temperature, BT14</description>
|
||||
</channel>
|
||||
<channel id="40017" typeId="type-temperature">
|
||||
<label>EB100-EP14-BT12 Condensor Out</label>
|
||||
<description>Condensor out temperature, BT12</description>
|
||||
</channel>
|
||||
<channel id="40020" typeId="type-temperature">
|
||||
<label>EB100-BT16 Evaporator Temp</label>
|
||||
<description>Evaporator Temp (BT16)</description>
|
||||
</channel>
|
||||
<channel id="43136" typeId="type-frequency-scale10">
|
||||
<label>Compressor Frequency, Actual</label>
|
||||
<description>The compressor frequency the compressor is currently running at</description>
|
||||
</channel>
|
||||
<channel id="43122" typeId="type-frequency-unscaled">
|
||||
<label>Compr. Current Min.freq.</label>
|
||||
<description>The current minimum frequency of the compressor</description>
|
||||
</channel>
|
||||
<channel id="43123" typeId="type-frequency-unscaled">
|
||||
<label>Compr. Current Max.freq.</label>
|
||||
<description>The current maximum frequency of the compressor</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="f750-airsupply">
|
||||
<label>Air Supply/Exhaust Channels</label>
|
||||
<channels>
|
||||
<channel id="40025" typeId="type-temperature">
|
||||
<label>BT20 Exhaust Air Temp. 1</label>
|
||||
<description>Exhaust Air Temperature (BT20)</description>
|
||||
</channel>
|
||||
<channel id="40026" typeId="type-temperature">
|
||||
<label>BT21 Vented Air Temp. 1</label>
|
||||
<description>Vented Air Temperature (BT21)</description>
|
||||
</channel>
|
||||
<channel id="43124" typeId="type-number-scale10">
|
||||
<label>Airflow Ref.</label>
|
||||
<description>Reference value for the airflow.</description>
|
||||
</channel>
|
||||
<channel id="41026" typeId="type-number-unscaled">
|
||||
<label>EB100-Adjusted BS1 Air Flow</label>
|
||||
<description>Adjusted BS1 Air Flow (BT100)</description>
|
||||
</channel>
|
||||
<channel id="47260" typeId="rwtype-fan-speed">
|
||||
<label>Selected Fan Speed</label>
|
||||
<description>Currently selected fan speed</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.2</property>
|
||||
<property name="validationExpression">[01234]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="f750" extensible="type-number-unscaled,type-number-scale10,type-number-scale100">
|
||||
<label>Nibe F750</label>
|
||||
<description>Nibe F750 heat pump connected through Nibe UpLink</description>
|
||||
<channel-groups>
|
||||
<channel-group typeId="base-base" id="base"/>
|
||||
<channel-group typeId="base-hotwater" id="hotwater"/>
|
||||
<channel-group typeId="f750-compressor" id="compressor"/>
|
||||
<channel-group typeId="f750-airsupply" id="airsupply"/>
|
||||
</channel-groups>
|
||||
<config-description-ref uri="thing-type:nibeuplink:web"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<channel-type id="type-number-unscaled">
|
||||
<item-type>Number</item-type>
|
||||
<label>Unnamed Number</label>
|
||||
<state pattern="%d" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-number-scale10">
|
||||
<item-type>Number</item-type>
|
||||
<label>Unnamed Number (0.1)</label>
|
||||
<state pattern="%.1f" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-number-scale100">
|
||||
<item-type>Number</item-type>
|
||||
<label>Unnamed Number (0.01)</label>
|
||||
<state pattern="%.2f" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-switch">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Unnamed Switch</label>
|
||||
<state readOnly="true"></state>
|
||||
</channel-type>
|
||||
<channel-type id="type-temperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Unnamed Temperature</label>
|
||||
<state pattern="%.1f %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-flow">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Unnamed Flow</label>
|
||||
<state pattern="%.1f l/min" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-electric-current">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Unnamed Current</label>
|
||||
<state pattern="%.1f %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-time-unscaled">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Unnamed Time</label>
|
||||
<state pattern="%d %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-time-scale10">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Unnamed Time</label>
|
||||
<state pattern="%.1f %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-frequency-unscaled">
|
||||
<item-type>Number:Frequency</item-type>
|
||||
<label>Unnamed Frequency</label>
|
||||
<state pattern="%d %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-frequency-scale10">
|
||||
<item-type>Number:Frequency</item-type>
|
||||
<label>Unnamed Frequency</label>
|
||||
<state pattern="%d %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-power">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Unnamed Power</label>
|
||||
<state pattern="%.2f %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-energy">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Unnamed Energy</label>
|
||||
<state pattern="%.1f %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-pressure">
|
||||
<item-type>Number:Pressure</item-type>
|
||||
<label>Unnamed Pressure</label>
|
||||
<state pattern="%.1f %unit%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-speed-percent">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Unnamed Speed</label>
|
||||
<state pattern="%d %%" readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-defrosting-state">
|
||||
<item-type>Number</item-type>
|
||||
<label>Defrosting State</label>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No</option>
|
||||
<option value="1">Active</option>
|
||||
<option value="2">Passive</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="type-hpac-state">
|
||||
<item-type>Number</item-type>
|
||||
<label>HPAC State</label>
|
||||
<state pattern="%d" readOnly="true">
|
||||
<options>
|
||||
<option value="10">Off</option>
|
||||
<option value="20">Wait</option>
|
||||
<option value="30">Passive</option>
|
||||
<option value="40">PassiveWait</option>
|
||||
<option value="50">Active</option>
|
||||
<option value="60">ActiveWait</option>
|
||||
<option value="70">ActiveProtWait</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<channel-type id="rwtype-heat-offset">
|
||||
<item-type>Number</item-type>
|
||||
<label>Heat Offset</label>
|
||||
<state min="-10" max="10" step="1" pattern="%d" readOnly="false">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-start-cooling">
|
||||
<item-type>Number</item-type>
|
||||
<label>Start Temperature Cooling</label>
|
||||
<state min="15" max="40" step="1" pattern="%d °C" readOnly="false">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-stop-heating">
|
||||
<item-type>Number</item-type>
|
||||
<label>Stop Temperature Heating</label>
|
||||
<state min="0" max="25" step="1" pattern="%d °C" readOnly="false">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-stop-add-heating">
|
||||
<item-type>Number</item-type>
|
||||
<label>Stop Temperature Additive</label>
|
||||
<state min="-20" max="10" step="1" pattern="%d °C" readOnly="false">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-filter-time">
|
||||
<item-type>Number</item-type>
|
||||
<label>Outdoor Filter Time</label>
|
||||
<state min="1" max="48" step="1" pattern="%d h" readOnly="false">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-room-sensor-factor">
|
||||
<item-type>Number</item-type>
|
||||
<label>Room Sensor Factor</label>
|
||||
<state min="0" max="6" step="1" pattern="%.1f" readOnly="false">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-switch">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Unnamed Switch</label>
|
||||
<state readOnly="false"></state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-degree-minutes">
|
||||
<item-type>Number</item-type>
|
||||
<label>Unnamed Degree Minutes</label>
|
||||
<state min="-30000" max="30000" step="1" pattern="%d °*min" readOnly="false">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-hw-lux">
|
||||
<item-type>Number</item-type>
|
||||
<label>Temporary Lux</label>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="0">Off</option>
|
||||
<option value="1">3h</option>
|
||||
<option value="2">6h</option>
|
||||
<option value="3">12h</option>
|
||||
<option value="4">One time</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-hw-mode">
|
||||
<item-type>Number</item-type>
|
||||
<label>Hot Water Mode</label>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="0">Economy</option>
|
||||
<option value="1">Normal</option>
|
||||
<option value="2">Luxury</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="rwtype-fan-speed">
|
||||
<item-type>Number</item-type>
|
||||
<label>Selected Fan Speed</label>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="0">normal</option>
|
||||
<option value="1">speed 1</option>
|
||||
<option value="2">speed 2</option>
|
||||
<option value="3">speed 3</option>
|
||||
<option value="4">speed 4</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-group-type id="vvm310-general">
|
||||
<label>General Channels</label>
|
||||
<channels>
|
||||
<channel id="44270" typeId="type-temperature">
|
||||
<label>Calc. Cooling Supply S1</label>
|
||||
<description>Calculated supply temperature in cooling mode for the climate system</description>
|
||||
</channel>
|
||||
<channel id="40121" typeId="type-temperature">
|
||||
<label>BT63 Add Supply Temp</label>
|
||||
<description>Supply Temp at internal additional heater (BT63)</description>
|
||||
</channel>
|
||||
<channel id="44302" typeId="type-energy">
|
||||
<label>Heat Meter - Cooling Cpr EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="47011" typeId="rwtype-heat-offset">
|
||||
<label>Heat Offset S1</label>
|
||||
<description>Offset of the heat curve, see manual for more information</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.1.1-S1</property>
|
||||
<property name="validationExpression">[-1]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47394" typeId="rwtype-switch">
|
||||
<label>Use Room Sensor S1</label>
|
||||
<description>When activated the system uses the room sensor 0=Off 1=On</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.4</property>
|
||||
<property name="validationExpression">.*</property>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47402" typeId="rwtype-room-sensor-factor">
|
||||
<label>Room Sensor Factor S1</label>
|
||||
<description>Setting of how much the difference between set and actual room temperature should affect the supply
|
||||
temperature.</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.4</property>
|
||||
<property name="validationExpression">[0123456]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="48793" typeId="rwtype-room-sensor-factor">
|
||||
<label>Room Sensor Cool Factor S1</label>
|
||||
<description>Setting of how much the difference between set and actual room temperature should affect the supply
|
||||
temperature in cooling mode.</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.4</property>
|
||||
<property name="validationExpression">[0123456]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="vvm310-compressor">
|
||||
<label>Compressor Channels</label>
|
||||
<channels>
|
||||
<channel id="44362" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT28 Outdoor Temp</label>
|
||||
<description>Current outdoor temperature, BT28</description>
|
||||
</channel>
|
||||
<channel id="44396" typeId="type-speed-percent">
|
||||
<label>EB101 Speed Charge Pump</label>
|
||||
<description>Speed Charge Pump</description>
|
||||
</channel>
|
||||
<channel id="44703" typeId="type-defrosting-state">
|
||||
<label>EB101-EP14 Defrosting Outdoor Unit</label>
|
||||
<description>Defrosting state of the outdoor unit</description>
|
||||
</channel>
|
||||
<channel id="44073" typeId="type-time-unscaled">
|
||||
<label>EB101-EP14 Tot. HW Op.time Compr</label>
|
||||
<description>Total operation time of compressor in hotwater mode</description>
|
||||
</channel>
|
||||
<channel id="40737" typeId="type-time-unscaled">
|
||||
<label>EB101-EP14 Tot. Cooling Op.time Compr</label>
|
||||
<description>Total operation time of compressor in cooling mode</description>
|
||||
</channel>
|
||||
<channel id="44071" typeId="type-time-unscaled">
|
||||
<label>EB101-EP14 Tot. Op.time Compr</label>
|
||||
<description>Total operation time of compressor</description>
|
||||
</channel>
|
||||
<channel id="44069" typeId="type-number-unscaled">
|
||||
<label>EB101-EP14 Compressor Starts</label>
|
||||
<description>Total compressor starts</description>
|
||||
</channel>
|
||||
<channel id="44061" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT17 Suction</label>
|
||||
<description>Suction temperature, BT17</description>
|
||||
</channel>
|
||||
<channel id="44060" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT15 Liquid Line</label>
|
||||
<description>Liquid line temperature, BT15</description>
|
||||
</channel>
|
||||
<channel id="44059" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT14 Hot Gas Temp</label>
|
||||
<description>Hot gas temperature, BT14</description>
|
||||
</channel>
|
||||
<channel id="44058" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT12 Condensor Out</label>
|
||||
<description>Condensor temperature, BT12</description>
|
||||
</channel>
|
||||
<channel id="44055" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT3 Return Temp.</label>
|
||||
<description>Return temperature, BT3</description>
|
||||
</channel>
|
||||
<channel id="44363" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT16 Evaporator</label>
|
||||
<description>Evaporator temperature, BT16</description>
|
||||
</channel>
|
||||
<channel id="44699" typeId="type-pressure">
|
||||
<label>EB101-EP14-BT4 Pressure Sensor</label>
|
||||
<description>Pressure Sensor (BT4)</description>
|
||||
</channel>
|
||||
<channel id="40782" typeId="type-frequency-unscaled">
|
||||
<label>EB101 Cpr Frequency Desired F2040</label>
|
||||
<description>The desired frequency as shown in service info</description>
|
||||
</channel>
|
||||
<channel id="44701" typeId="type-frequency-scale10">
|
||||
<label>EB101-EP14 Actual Cpr Frequency Outdoor Unit</label>
|
||||
<description>Actual compressor frequency of the outdoor unit</description>
|
||||
</channel>
|
||||
<channel id="44702" typeId="type-switch">
|
||||
<label>EB101-EP14 Protection Status Register Outdoor Unit</label>
|
||||
<description>rotection status register of the outdoor unit</description>
|
||||
<properties>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="44700" typeId="type-pressure">
|
||||
<label>EB101-EP14 Low Pressure Sensor Outdoor Unit</label>
|
||||
<description>Low pressure sensor outdoor unit</description>
|
||||
</channel>
|
||||
<channel id="44457" typeId="type-number-unscaled">
|
||||
<label>EB101-EP14 Compressor State</label>
|
||||
<description>Compressor state</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="vvm310-airsupply">
|
||||
<label>Air Supply/Exhaust Channels</label>
|
||||
<channels>
|
||||
<channel id="40025" typeId="type-temperature">
|
||||
<label>BT20 Exhaust Air Temp. 1</label>
|
||||
<description>Exhaust Air Temperature (BT20)</description>
|
||||
</channel>
|
||||
<channel id="40026" typeId="type-temperature">
|
||||
<label>BT21 Vented Air Temp. 1</label>
|
||||
<description>Vented Air Temperature (BT21)</description>
|
||||
</channel>
|
||||
<channel id="40075" typeId="type-temperature">
|
||||
<label>BT22 Supply Air Temp.</label>
|
||||
<description>Supply Air Temperature (BT22)</description>
|
||||
</channel>
|
||||
<channel id="40183" typeId="type-temperature">
|
||||
<label>AZ30-BT23 Outdoor Temp. ERS</label>
|
||||
<description>Outdoor Temperature (BT23)</description>
|
||||
</channel>
|
||||
<channel id="40311" typeId="type-speed-percent">
|
||||
<label>External ERS Accessory GQ2 Speed</label>
|
||||
<description>Indicates the speed of the GQ2 fan speed on the ERS accessory.</description>
|
||||
</channel>
|
||||
<channel id="40312" typeId="type-speed-percent">
|
||||
<label>External ERS Accessory GQ3 Speed</label>
|
||||
<description>Indicates the speed of the GQ3 fan speed on the ERS accessory.</description>
|
||||
</channel>
|
||||
<channel id="40942" typeId="type-switch">
|
||||
<label>External ERS Accessory Block Status</label>
|
||||
<description>Indicates if the ERS accessory is externaly blocked.</description>
|
||||
<properties>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47260" typeId="rwtype-fan-speed">
|
||||
<label>Selected Fan Speed</label>
|
||||
<description>Currently selected fan speed</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.2</property>
|
||||
<property name="validationExpression">[01234]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="vvm310" extensible="type-number-unscaled,type-number-scale10,type-number-scale100">
|
||||
<label>Nibe VVM310 / VVM500</label>
|
||||
<description>Nibe VVM310 / VVM500 heat pump connected through Nibe UpLink</description>
|
||||
<channel-groups>
|
||||
<channel-group typeId="base-base" id="base"/>
|
||||
<channel-group typeId="base-hotwater" id="hotwater"/>
|
||||
<channel-group typeId="vvm310-general" id="general"/>
|
||||
<channel-group typeId="vvm310-compressor" id="compressor"/>
|
||||
<channel-group typeId="vvm310-airsupply" id="airsupply"/>
|
||||
</channel-groups>
|
||||
<config-description-ref uri="thing-type:nibeuplink:web"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,221 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-group-type id="vvm320-general">
|
||||
<label>General Channels</label>
|
||||
<channels>
|
||||
<channel id="44270" typeId="type-temperature">
|
||||
<label>Calc. Cooling Supply S1</label>
|
||||
<description>Calculated supply temperature in cooling mode for the climate system</description>
|
||||
</channel>
|
||||
<channel id="40121" typeId="type-temperature">
|
||||
<label>BT63 Add Supply Temp</label>
|
||||
<description>Supply Temp at internal additional heater (BT63)</description>
|
||||
</channel>
|
||||
<channel id="44302" typeId="type-energy">
|
||||
<label>Heat Meter - Cooling Cpr EP14</label>
|
||||
<description>Accumulated energy production as calculated by the heat meter</description>
|
||||
</channel>
|
||||
<channel id="47011" typeId="rwtype-heat-offset">
|
||||
<label>Heat Offset S1</label>
|
||||
<description>Offset of the heat curve, see manual for more information</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.1.1-S1</property>
|
||||
<property name="validationExpression">[-1]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47394" typeId="rwtype-switch">
|
||||
<label>Use Room Sensor S1</label>
|
||||
<description>When activated the system uses the room sensor 0=Off 1=On</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.4</property>
|
||||
<property name="validationExpression">.*</property>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47402" typeId="rwtype-room-sensor-factor">
|
||||
<label>Room Sensor Factor S1</label>
|
||||
<description>Setting of how much the difference between set and actual room temperature should affect the supply
|
||||
temperature.</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.4</property>
|
||||
<property name="validationExpression">[0123456]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="48793" typeId="rwtype-room-sensor-factor">
|
||||
<label>Room Sensor Cool Factor S1</label>
|
||||
<description>Setting of how much the difference between set and actual room temperature should affect the supply
|
||||
temperature in cooling mode.</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.9.4</property>
|
||||
<property name="validationExpression">[0123456]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47374" typeId="rwtype-start-cooling">
|
||||
<label>Start Temperature Cooling</label>
|
||||
<description>Start Temperature Cooling in Auto mode</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/4.9.2</property>
|
||||
<property name="validationExpression">[0-9]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47375" typeId="rwtype-stop-heating">
|
||||
<label>Stop Temperature Heating</label>
|
||||
<description>Stop Temperature Heating in Auto mode</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/4.9.2</property>
|
||||
<property name="validationExpression">[0-9]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47376" typeId="rwtype-stop-add-heating">
|
||||
<label>Stop Temperature Additive</label>
|
||||
<description>Stop Temperature Additive heater in Auto mode</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/4.9.2</property>
|
||||
<property name="validationExpression">[0-9]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47377" typeId="rwtype-filter-time">
|
||||
<label>Outdoor Filter Time</label>
|
||||
<description>Outdoor Filter Time in Auto mode</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/4.9.2</property>
|
||||
<property name="validationExpression">[0-4]*[0-9]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="vvm320-compressor">
|
||||
<label>Compressor Channels</label>
|
||||
<channels>
|
||||
<channel id="44362" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT28 Outdoor Temp</label>
|
||||
<description>Current outdoor temperature, BT28</description>
|
||||
</channel>
|
||||
<channel id="44396" typeId="type-speed-percent">
|
||||
<label>EB101 Speed Charge Pump</label>
|
||||
<description>Speed Charge Pump</description>
|
||||
</channel>
|
||||
<channel id="44703" typeId="type-defrosting-state">
|
||||
<label>EB101-EP14 Defrosting Outdoor Unit</label>
|
||||
<description>Defrosting state of the outdoor unit</description>
|
||||
</channel>
|
||||
<channel id="44073" typeId="type-time-unscaled">
|
||||
<label>EB101-EP14 Tot. HW Op.time Compr</label>
|
||||
<description>Total operation time of compressor in hotwater mode</description>
|
||||
</channel>
|
||||
<channel id="40737" typeId="type-time-unscaled">
|
||||
<label>EB101-EP14 Tot. Cooling Op.time Compr</label>
|
||||
<description>Total operation time of compressor in cooling mode</description>
|
||||
</channel>
|
||||
<channel id="44071" typeId="type-time-unscaled">
|
||||
<label>EB101-EP14 Tot. Op.time Compr</label>
|
||||
<description>Total operation time of compressor</description>
|
||||
</channel>
|
||||
<channel id="44069" typeId="type-number-unscaled">
|
||||
<label>EB101-EP14 Compressor Starts</label>
|
||||
<description>Total compressor starts</description>
|
||||
</channel>
|
||||
<channel id="44061" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT17 Suction</label>
|
||||
<description>Suction temperature, BT17</description>
|
||||
</channel>
|
||||
<channel id="44060" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT15 Liquid Line</label>
|
||||
<description>Liquid line temperature, BT15</description>
|
||||
</channel>
|
||||
<channel id="44059" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT14 Hot Gas Temp</label>
|
||||
<description>Hot gas temperature, BT14</description>
|
||||
</channel>
|
||||
<channel id="44058" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT12 Condensor Out</label>
|
||||
<description>Condensor temperature, BT12</description>
|
||||
</channel>
|
||||
<channel id="44055" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT3 Return Temp.</label>
|
||||
<description>Return temperature, BT3</description>
|
||||
</channel>
|
||||
<channel id="44363" typeId="type-temperature">
|
||||
<label>EB101-EP14-BT16 Evaporator</label>
|
||||
<description>Evaporator temperature, BT16</description>
|
||||
</channel>
|
||||
<channel id="44699" typeId="type-pressure">
|
||||
<label>EB101-EP14-BT4 Pressure Sensor</label>
|
||||
<description>Pressure Sensor (BT4)</description>
|
||||
</channel>
|
||||
<channel id="40782" typeId="type-frequency-unscaled">
|
||||
<label>EB101 Cpr Frequency Desired F2040</label>
|
||||
<description>The desired frequency as shown in service info</description>
|
||||
</channel>
|
||||
<channel id="44701" typeId="type-frequency-scale10">
|
||||
<label>EB101-EP14 Actual Cpr Frequency Outdoor Unit</label>
|
||||
<description>Actual compressor frequency of the outdoor unit</description>
|
||||
</channel>
|
||||
<channel id="44702" typeId="type-switch">
|
||||
<label>EB101-EP14 Protection Status Register Outdoor Unit</label>
|
||||
<description>rotection status register of the outdoor unit</description>
|
||||
<properties>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="44700" typeId="type-pressure">
|
||||
<label>EB101-EP14 Low Pressure Sensor Outdoor Unit</label>
|
||||
<description>Low pressure sensor outdoor unit</description>
|
||||
</channel>
|
||||
<channel id="44457" typeId="type-number-unscaled">
|
||||
<label>EB101-EP14 Compressor State</label>
|
||||
<description>Compressor state</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="vvm320-airsupply">
|
||||
<label>Air Supply/Exhaust Channels</label>
|
||||
<channels>
|
||||
<channel id="40025" typeId="type-temperature">
|
||||
<label>BT20 Exhaust Air Temp. 1</label>
|
||||
<description>Exhaust Air Temperature (BT20)</description>
|
||||
</channel>
|
||||
<channel id="40026" typeId="type-temperature">
|
||||
<label>BT21 Vented Air Temp. 1</label>
|
||||
<description>Vented Air Temperature (BT21)</description>
|
||||
</channel>
|
||||
<channel id="40075" typeId="type-temperature">
|
||||
<label>BT22 Supply Air Temp.</label>
|
||||
<description>Supply Air Temperature (BT22)</description>
|
||||
</channel>
|
||||
<channel id="40183" typeId="type-temperature">
|
||||
<label>AZ30-BT23 Outdoor Temp. ERS</label>
|
||||
<description>Outdoor Temperature (BT23)</description>
|
||||
</channel>
|
||||
<channel id="40311" typeId="type-speed-percent">
|
||||
<label>External ERS Accessory GQ2 Speed</label>
|
||||
<description>Indicates the speed of the GQ2 fan speed on the ERS accessory.</description>
|
||||
</channel>
|
||||
<channel id="40312" typeId="type-speed-percent">
|
||||
<label>External ERS Accessory GQ3 Speed</label>
|
||||
<description>Indicates the speed of the GQ3 fan speed on the ERS accessory.</description>
|
||||
</channel>
|
||||
<channel id="40942" typeId="type-switch">
|
||||
<label>External ERS Accessory Block Status</label>
|
||||
<description>Indicates if the ERS accessory is externaly blocked.</description>
|
||||
<properties>
|
||||
<property name="offMapping">0</property>
|
||||
<property name="onMapping">1</property>
|
||||
</properties>
|
||||
</channel>
|
||||
<channel id="47260" typeId="rwtype-fan-speed">
|
||||
<label>Selected Fan Speed</label>
|
||||
<description>Currently selected fan speed</description>
|
||||
<properties>
|
||||
<property name="writeApiUrl">/Manage/1.2</property>
|
||||
<property name="validationExpression">[01234]</property>
|
||||
</properties>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="nibeuplink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="vvm320" extensible="type-number-unscaled,type-number-scale10,type-number-scale100">
|
||||
<label>Nibe VVM320 / VVM325</label>
|
||||
<description>Nibe VVM320 / VVM325 heat pump connected through Nibe UpLink</description>
|
||||
<channel-groups>
|
||||
<channel-group typeId="base-base" id="base"/>
|
||||
<channel-group typeId="base-hotwater" id="hotwater"/>
|
||||
<channel-group typeId="vvm320-general" id="general"/>
|
||||
<channel-group typeId="vvm320-compressor" id="compressor"/>
|
||||
<channel-group typeId="vvm320-airsupply" id="airsupply"/>
|
||||
</channel-groups>
|
||||
<config-description-ref uri="thing-type:nibeuplink:web"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user