added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.modbus.helioseasycontrols-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>file:${basedirRoot}/bundles/org.openhab.io.transport.modbus/target/feature/feature.xml</repository>
|
||||
|
||||
<feature name="openhab-binding-modbus.helioseasycontrols" description="Modbus.HeliosEasyControls Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transport-modbus</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.modbus/${project.version}</bundle>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.modbus.helioseasycontrols/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* 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.modbus.helioseasycontrols.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.annotation.ActionInput;
|
||||
import org.openhab.core.automation.annotation.RuleAction;
|
||||
import org.openhab.core.thing.binding.ThingActions;
|
||||
import org.openhab.core.thing.binding.ThingActionsScope;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This class provides the actions available for the Helios device
|
||||
*
|
||||
* @author Bernhard Bauer - Initial contribution
|
||||
*/
|
||||
@ThingActionsScope(name = "modbus.helioseasycontrols")
|
||||
@NonNullByDefault
|
||||
public class HeliosEasyControlsActions implements ThingActions {
|
||||
|
||||
private @Nullable HeliosEasyControlsHandler handler;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HeliosEasyControlsActions.class);
|
||||
|
||||
@Override
|
||||
public void setThingHandler(@Nullable ThingHandler handler) {
|
||||
this.handler = (HeliosEasyControlsHandler) handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingHandler getThingHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
private void triggerSwitch(String variableName) {
|
||||
try {
|
||||
if (this.handler != null) {
|
||||
this.handler.writeValue(variableName, "1");
|
||||
}
|
||||
} catch (HeliosException e) {
|
||||
logger.warn("Error executing action 'resetFilterChangeTimer': {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@RuleAction(label = "Reset filter change timer", description = "Sets the filter change timer back to the configured interval")
|
||||
public void resetFilterChangeTimer() {
|
||||
this.triggerSwitch(HeliosEasyControlsBindingConstants.FILTER_CHANGE_RESET);
|
||||
}
|
||||
|
||||
public static void resetFilterChangeTimer(@Nullable ThingActions actions) {
|
||||
if (actions instanceof HeliosEasyControlsActions) {
|
||||
((HeliosEasyControlsActions) actions).resetFilterChangeTimer();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an HeliosEasyControlsActions class.");
|
||||
}
|
||||
}
|
||||
|
||||
@RuleAction(label = "Reset error messages", description = "Reset error/warning/info messages")
|
||||
public void resetErrors() {
|
||||
this.triggerSwitch(HeliosEasyControlsBindingConstants.RESET_FLAG);
|
||||
}
|
||||
|
||||
public static void resetErrors(@Nullable ThingActions actions) {
|
||||
if (actions instanceof HeliosEasyControlsActions) {
|
||||
((HeliosEasyControlsActions) actions).resetErrors();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an HeliosEasyControlsActions class.");
|
||||
}
|
||||
}
|
||||
|
||||
@RuleAction(label = "Reset to factory defaults", description = "Reset device to factory defaults")
|
||||
public void resetToFactoryDefaults() {
|
||||
this.triggerSwitch(HeliosEasyControlsBindingConstants.FACTORY_RESET);
|
||||
}
|
||||
|
||||
public static void resetToFactoryDefaults(@Nullable ThingActions actions) {
|
||||
if (actions instanceof HeliosEasyControlsActions) {
|
||||
((HeliosEasyControlsActions) actions).resetToFactoryDefaults();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an HeliosEasyControlsActions class.");
|
||||
}
|
||||
}
|
||||
|
||||
@RuleAction(label = "Reset individual switching times", description = "Reset individual switching times")
|
||||
public void resetSwitchingTimes() {
|
||||
this.triggerSwitch(HeliosEasyControlsBindingConstants.FACTORY_SETTING_WZU);
|
||||
}
|
||||
|
||||
public static void resetSwitchingTimes(@Nullable ThingActions actions) {
|
||||
if (actions instanceof HeliosEasyControlsActions) {
|
||||
((HeliosEasyControlsActions) actions).resetSwitchingTimes();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an HeliosEasyControlsActions class.");
|
||||
}
|
||||
}
|
||||
|
||||
@RuleAction(label = "Set system date and time", description = "Sets the device's system date and time based on OH's system date and time")
|
||||
public void setSysDateTime() {
|
||||
HeliosEasyControlsHandler handler = this.handler;
|
||||
if (handler != null) {
|
||||
handler.setSysDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
public static void setSysDateTime(@Nullable ThingActions actions) {
|
||||
if (actions instanceof HeliosEasyControlsActions) {
|
||||
((HeliosEasyControlsActions) actions).setSysDateTime();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an HeliosEasyControlsActions class.");
|
||||
}
|
||||
}
|
||||
|
||||
private void setBypass(boolean from, int day, int month) {
|
||||
HeliosEasyControlsHandler handler = this.handler;
|
||||
if (handler != null) {
|
||||
handler.setBypass(from, day, month);
|
||||
}
|
||||
}
|
||||
|
||||
@RuleAction(label = "Set the bypass from day and month", description = "Sets the day and month from when the bypass should be active")
|
||||
public void setBypassFrom(
|
||||
@ActionInput(name = "day", label = "bypass from day", description = "The day from when the bypass should be active") int day,
|
||||
@ActionInput(name = "month", label = "bypass from month", description = "The month from when the bypass should be active") int month) {
|
||||
this.setBypass(true, day, month);
|
||||
}
|
||||
|
||||
public static void setBypassFrom(@Nullable ThingActions actions, int day, int month) {
|
||||
if (actions instanceof HeliosEasyControlsActions) {
|
||||
((HeliosEasyControlsActions) actions).setBypassFrom(day, month);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an HeliosEasyControlsActions class.");
|
||||
}
|
||||
}
|
||||
|
||||
@RuleAction(label = "Set the bypass to day and month", description = "Sets the day and month until when the bypass should be active")
|
||||
public void setBypassTo(
|
||||
@ActionInput(name = "day", label = "bypass to day", description = "The day until when the bypass should be active") int day,
|
||||
@ActionInput(name = "month", label = "bypass to month", description = "The month until when the bypass should be active") int month) {
|
||||
this.setBypass(false, day, month);
|
||||
}
|
||||
|
||||
public static void setBypassTo(@Nullable ThingActions actions, int day, int month) {
|
||||
if (actions instanceof HeliosEasyControlsActions) {
|
||||
((HeliosEasyControlsActions) actions).setBypassTo(day, month);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Instance is not an HeliosEasyControlsActions class.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
/**
|
||||
* 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.modbus.helioseasycontrols.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.modbus.ModbusBindingConstants;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link HeliosEasyControlsBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Bernhard Bauer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeliosEasyControlsBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = ModbusBindingConstants.BINDING_ID;
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_HELIOS_VENTILATION_EASY_CONTROLS = new ThingTypeUID(BINDING_ID,
|
||||
"helios-easycontrols");
|
||||
|
||||
// List of all Channel IDs
|
||||
// -----------------------
|
||||
// Device Config
|
||||
public final static String SYS_DATE = "sysdate"; // for the combined item (based on DATE, TIME and
|
||||
// TIME_ZONE_DIFFERENCE_TO_GMT)
|
||||
public final static String DATE = "date";
|
||||
public final static String TIME = "time";
|
||||
public final static String TIME_ZONE_DIFFERENCE_TO_GMT = "timeZoneDifferenceToGmt";
|
||||
public final static String SUMMER_WINTER = "summerWinter";
|
||||
public final static String ACCESS_HELIOS_PORTAL = "accessHeliosPortal";
|
||||
public final static String AUTO_SW_UPDATE = "autoSwUpdate";
|
||||
public final static String MIN_FAN_STAGE = "minFanStage";
|
||||
public final static String COMFORT_TEMP = "comfortTemp";
|
||||
public final static String SUPPLY_AIR_FAN_STAGE = "supplyAirFanStage";
|
||||
public final static String EXTRACT_AIR_FAN_STAGE = "extractAirFanStage";
|
||||
// Operation
|
||||
public final static String PARTY_MODE_DURATION = "partyModeDuration";
|
||||
public final static String PARTY_MODE_FAN_STAGE = "partyModeFanStage";
|
||||
public final static String PARTY_MODE_REMAINING_TIME = "partyModeRemainingTime";
|
||||
public final static String PARTY_MODE_STATUS = "partyModeStatus";
|
||||
public final static String STANDBY_MODE_DURATION = "standbyModeDuration";
|
||||
public final static String STANDBY_MODE_FAN_STAGE = "standbyModeFanStage";
|
||||
public final static String STANDBY_MODE_REMAINING_TIME = "standbyModeRemainingTime";
|
||||
public final static String STANDBY_MODE_STATUS = "standbyModeStatus";
|
||||
public final static String HOLIDAY_PROGRAMME = "holidayProgramme";
|
||||
public final static String HOLIDAY_PROGRAMME_FAN_STAGE = "holidayProgrammeFanStage";
|
||||
public final static String HOLIDAY_PROGRAMME_START = "holidayProgrammeStart";
|
||||
public final static String HOLIDAY_PROGRAMME_END = "holidayProgrammeEnd";
|
||||
public final static String HOLIDAY_PROGRAMME_INTERVAL = "holidayProgrammeInterval";
|
||||
public final static String HOLIDAY_PROGRAMME_ACTIVATION_TIME = "holidayProgrammeActivationTime";
|
||||
public final static String OPERATING_MODE = "operatingMode";
|
||||
public final static String FAN_STAGE = "fanStage";
|
||||
public final static String PERCENTAGE_FAN_STAGE = "percentageFanStage";
|
||||
public final static String TEMPERATURE_OUTSIDE_AIR = "temperatureOutsideAir";
|
||||
public final static String TEMPERATURE_SUPPLY_AIR = "temperatureSupplyAir";
|
||||
public final static String TEMPERATURE_OUTGOING_AIR = "temperatureOutgoingAir";
|
||||
public final static String TEMPERATURE_EXTRACT_AIR = "temperatureExtractAir";
|
||||
public final static String VHZ_DUCT_SENSOR = "vhzDuctSensor";
|
||||
public final static String NHZ_DUCT_SENSOR = "nhzDuctSensor";
|
||||
public final static String NHZ_RETURN_SENSOR = "nhzReturnSensor";
|
||||
public final static String SUPPLY_AIR_RPM = "supplyAirRpm";
|
||||
public final static String EXTRACT_AIR_RPM = "extractAirRpm";
|
||||
public final static String OPERATING_HOURS_SUPPLY_AIR_VENT = "operatingHoursSupplyAirVent";
|
||||
public final static String OPERATING_HOURS_EXTRACT_AIR_VENT = "operatingHoursExtractAirVent";
|
||||
// Heater
|
||||
public final static String PRE_HEATER_STATUS = "preHeaterStatus";
|
||||
public final static String WEEK_PROFILE_NHZ = "weekProfileNhz";
|
||||
public final static String RUN_ON_TIME_VHZ_NHZ = "runOnTimeVhzNhz";
|
||||
public final static String OPERATING_HOURS_VHZ = "operatingHoursVhz";
|
||||
public final static String OPERATING_HOURS_NHZ = "operatingHoursNhz";
|
||||
public final static String OUTPUT_POWER_VHZ = "outputPowerVhz";
|
||||
public final static String OUTPUT_POWER_NHZ = "outputPowerNhz";
|
||||
// Humidity control
|
||||
public final static String HUMIDITY_CONTROL_SET_VALUE = "humidityControlSetValue";
|
||||
public final static String HUMIDITY_CONTROL_STEPS = "humidityControlSteps";
|
||||
public final static String HUMIDITY_STOP_TIME = "humidityStopTime";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_1 = "externalSensorKwlFtfHumidity1";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_2 = "externalSensorKwlFtfHumidity2";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_3 = "externalSensorKwlFtfHumidity3";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_4 = "externalSensorKwlFtfHumidity4";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_5 = "externalSensorKwlFtfHumidity5";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_6 = "externalSensorKwlFtfHumidity6";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_7 = "externalSensorKwlFtfHumidity7";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_HUMIDITY_8 = "externalSensorKwlFtfHumidity8";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_1 = "externalSensorKwlFtfTemperature1";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_2 = "externalSensorKwlFtfTemperature2";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_3 = "externalSensorKwlFtfTemperature3";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_4 = "externalSensorKwlFtfTemperature4";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_5 = "externalSensorKwlFtfTemperature5";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_6 = "externalSensorKwlFtfTemperature6";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_7 = "externalSensorKwlFtfTemperature7";
|
||||
public final static String EXTERNAL_SENSOR_KWL_FTF_TEMPERATURE_8 = "externalSensorKwlFtfTemperature8";
|
||||
// CO2 control
|
||||
public final static String CO2_CONTROL_SET_VALUE = "co2ControlSetValue";
|
||||
public final static String CO2_CONTROL_STEPS = "co2ControlSteps";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_1 = "externalSensorKwlCo21";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_2 = "externalSensorKwlCo22";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_3 = "externalSensorKwlCo23";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_4 = "externalSensorKwlCo24";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_5 = "externalSensorKwlCo25";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_6 = "externalSensorKwlCo26";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_7 = "externalSensorKwlCo27";
|
||||
public final static String EXTERNAL_SENSOR_KWL_CO2_8 = "externalSensorKwlCo28";
|
||||
public final static String SENSOR_NAME_CO2_1 = "sensorNameCo21";
|
||||
public final static String SENSOR_NAME_CO2_2 = "sensorNameCo22";
|
||||
public final static String SENSOR_NAME_CO2_3 = "sensorNameCo23";
|
||||
public final static String SENSOR_NAME_CO2_4 = "sensorNameCo24";
|
||||
public final static String SENSOR_NAME_CO2_5 = "sensorNameCo25";
|
||||
public final static String SENSOR_NAME_CO2_6 = "sensorNameCo26";
|
||||
public final static String SENSOR_NAME_CO2_7 = "sensorNameCo27";
|
||||
public final static String SENSOR_NAME_CO2_8 = "sensorNameCo28";
|
||||
// VOC control
|
||||
public final static String VOC_CONTROL_SET_VALUE = "vocControlSetValue";
|
||||
public final static String VOC_CONTROL_STEPS = "vocControlSteps";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_1 = "externalSensorKwlVoc1";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_2 = "externalSensorKwlVoc2";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_3 = "externalSensorKwlVoc3";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_4 = "externalSensorKwlVoc4";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_5 = "externalSensorKwlVoc5";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_6 = "externalSensorKwlVoc6";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_7 = "externalSensorKwlVoc7";
|
||||
public final static String EXTERNAL_SENSOR_KWL_VOC_8 = "externalSensorKwlVoc8";
|
||||
public final static String SENSOR_NAME_VOC_1 = "sensorNameVoc1";
|
||||
public final static String SENSOR_NAME_VOC_2 = "sensorNameVoc2";
|
||||
public final static String SENSOR_NAME_VOC_3 = "sensorNameVoc3";
|
||||
public final static String SENSOR_NAME_VOC_4 = "sensorNameVoc4";
|
||||
public final static String SENSOR_NAME_VOC_5 = "sensorNameVoc5";
|
||||
public final static String SENSOR_NAME_VOC_6 = "sensorNameVoc6";
|
||||
public final static String SENSOR_NAME_VOC_7 = "sensorNameVoc7";
|
||||
public final static String SENSOR_NAME_VOC_8 = "sensorNameVoc8";
|
||||
// Errors
|
||||
public final static String ERROR_OUTPUT_FUNCTION = "errorOutputFunction";
|
||||
public final static String ERRORS = "errors";
|
||||
public final static String WARNINGS = "warnings";
|
||||
public final static String INFOS = "infos";
|
||||
public final static String NO_OF_ERRORS = "noOfErrors";
|
||||
public final static String NO_OF_WARNINGS = "noOfWarnings";
|
||||
public final static String NO_OF_INFOS = "noOfInfos";
|
||||
public final static String ERRORS_MSG = "errorsMsg";
|
||||
public final static String WARNINGS_MSG = "warningsMsg";
|
||||
public final static String INFOS_MSG = "infosMsg";
|
||||
public final static String STATUS_FLAGS = "statusFlags";
|
||||
// Filter
|
||||
public final static String FILTER_CHANGE = "filterChange";
|
||||
public final static String FILTER_CHANGE_INTERVAL = "filterChangeInterval";
|
||||
public final static String FILTER_CHANGE_REMAINING_TIME = "filterChangeRemainingTime";
|
||||
// Bypass
|
||||
public final static String BYPASS_ROOM_TEMPERATURE = "bypassRoomTemperature";
|
||||
public final static String BYPASS_MIN_OUTSIDE_TEMPERATURE = "bypassMinOutsideTemperature";
|
||||
public final static String BYPASS_STATUS = "bypassStatus";
|
||||
public final static String BYPASS_FROM = "bypassFrom"; // for the combined item (based on BYPASS_FROM_DAY and
|
||||
// BYPASS_FROM_MONTH)
|
||||
public final static String BYPASS_FROM_DAY = "bypassFromDay";
|
||||
public final static String BYPASS_FROM_MONTH = "bypassFromMonth";
|
||||
public final static String BYPASS_TO = "bypassTo"; // for the combined item (based on BYPASS_TO_DAY and
|
||||
// BYPASS_TO_MONTH)
|
||||
public final static String BYPASS_TO_DAY = "bypassToDay";
|
||||
public final static String BYPASS_TO_MONTH = "bypassToMonth";
|
||||
|
||||
// List of all Properties
|
||||
// ----------------------
|
||||
// Device Config
|
||||
public final static String ARTICLE_DESCRIPTION = "articleDescription";
|
||||
public final static String REF_NO = "refNo";
|
||||
public final static String SER_NO = "serNo";
|
||||
public final static String PROD_CODE = "prodCode";
|
||||
public final static String MAC_ADDRESS = "macAddress";
|
||||
public final static String SOFTWARE_VERSION_BASIS = "softwareVersionBasis";
|
||||
public final static String DATE_FORMAT = "dateFormat";
|
||||
public final static String LANGUAGE = "language";
|
||||
public final static String UNIT_CONFIG = "unitConfig";
|
||||
public final static String KWL_BE = "kwlBe";
|
||||
public final static String KWL_BEC = "kwlBec";
|
||||
public final static String EXTERNAL_CONTACT = "externalContact";
|
||||
public final static String FUNCTION_TYPE_KWL_EM = "functionTypeKwlEm";
|
||||
public final static String HEAT_EXCHANGER_TYPE = "heatExchangerType";
|
||||
public final static String OFFSET_EXTRACT_AIR = "offsetExtractAir";
|
||||
public final static String ASSIGNMENT_FAN_STAGES = "assignmentFanStages";
|
||||
public final static String VOLTAGE_FAN_STAGE_1_EXTRACT_AIR = "voltageFanStage1ExtractAir";
|
||||
public final static String VOLTAGE_FAN_STAGE_2_EXTRACT_AIR = "voltageFanStage2ExtractAir";
|
||||
public final static String VOLTAGE_FAN_STAGE_3_EXTRACT_AIR = "voltageFanStage3ExtractAir";
|
||||
public final static String VOLTAGE_FAN_STAGE_4_EXTRACT_AIR = "voltageFanStage4ExtractAir";
|
||||
public final static String VOLTAGE_FAN_STAGE_1_SUPPLY_AIR = "voltageFanStage1SupplyAir";
|
||||
public final static String VOLTAGE_FAN_STAGE_2_SUPPLY_AIR = "voltageFanStage2SupplyAir";
|
||||
public final static String VOLTAGE_FAN_STAGE_3_SUPPLY_AIR = "voltageFanStage3SupplyAir";
|
||||
public final static String VOLTAGE_FAN_STAGE_4_SUPPLY_AIR = "voltageFanStage4SupplyAir";
|
||||
public final static String FAN_STAGE_STEPPED_0TO2V = "fanStageStepped0to2v";
|
||||
public final static String FAN_STAGE_STEPPED_2TO4V = "fanStageStepped2to4v";
|
||||
public final static String FAN_STAGE_STEPPED_4TO6V = "fanStageStepped4to6v";
|
||||
public final static String FAN_STAGE_STEPPED_6TO8V = "fanStageStepped6to8v";
|
||||
public final static String FAN_STAGE_STEPPED_8TO10V = "fanStageStepped8to10v";
|
||||
// Heater
|
||||
public final static String VHZ_TYPE = "vhzType";
|
||||
// Humidty control
|
||||
public final static String HUMIDITY_CONTROL_STATUS = "humidityControlStatus";
|
||||
public final static String KWL_FTF_CONFIG_0 = "kwlFtfConfig0";
|
||||
public final static String KWL_FTF_CONFIG_1 = "kwlFtfConfig1";
|
||||
public final static String KWL_FTF_CONFIG_2 = "kwlFtfConfig2";
|
||||
public final static String KWL_FTF_CONFIG_3 = "kwlFtfConfig3";
|
||||
public final static String KWL_FTF_CONFIG_4 = "kwlFtfConfig4";
|
||||
public final static String KWL_FTF_CONFIG_5 = "kwlFtfConfig5";
|
||||
public final static String KWL_FTF_CONFIG_6 = "kwlFtfConfig6";
|
||||
public final static String KWL_FTF_CONFIG_7 = "kwlFtfConfig7";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_1 = "sensorConfigKwlFtf1";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_2 = "sensorConfigKwlFtf2";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_3 = "sensorConfigKwlFtf3";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_4 = "sensorConfigKwlFtf4";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_5 = "sensorConfigKwlFtf5";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_6 = "sensorConfigKwlFtf6";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_7 = "sensorConfigKwlFtf7";
|
||||
public final static String SENSOR_CONFIG_KWL_FTF_8 = "sensorConfigKwlFtf8";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_1 = "sensorNameHumidityAndTemp1";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_2 = "sensorNameHumidityAndTemp2";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_3 = "sensorNameHumidityAndTemp3";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_4 = "sensorNameHumidityAndTemp4";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_5 = "sensorNameHumidityAndTemp5";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_6 = "sensorNameHumidityAndTemp6";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_7 = "sensorNameHumidityAndTemp7";
|
||||
public final static String SENSOR_NAME_HUMIDITY_AND_TEMP_8 = "sensorNameHumidityAndTemp8";
|
||||
// CO2 control
|
||||
public final static String CO2_CONTROL_STATUS = "co2ControlStatus";
|
||||
// VOC control
|
||||
public final static String VOC_CONTROL_STATUS = "vocControlStatus";
|
||||
|
||||
// List of all variables used in actions
|
||||
public final static String FILTER_CHANGE_RESET = "filterChangeReset";
|
||||
public final static String FACTORY_SETTING_WZU = "factorySettingWzu";
|
||||
public final static String FACTORY_RESET = "factoryReset";
|
||||
public final static String RESET_FLAG = "resetFlag";
|
||||
|
||||
// List of all unused variables (defined in the specification but not implemented as channels, properties or
|
||||
// actions)
|
||||
public final static String GLOBAL_MANUAL_WEB_UPDATE = "globalManualWebUpdate";
|
||||
public final static String PORTAL_GLOBALS_ERROR_FOR_WEB = "portalGlobalsErrorForWeb";
|
||||
public final static String CLEAR_ERROR = "clearError";
|
||||
public final static String TBD = "tbd";
|
||||
public final static String LOGOUT = "logout";
|
||||
|
||||
// List of all Configuration Parameters
|
||||
public final static String CONFIG_REFRESH_INTERVAL = "refreshInterval";
|
||||
|
||||
// Other constants
|
||||
public final static int UNIT_ID = 180;
|
||||
public final static int START_ADDRESS = 1;
|
||||
public final static String VARIABLES_DEFINITION_FILE = "variables.json";
|
||||
public final static int MAX_TRIES = 5;
|
||||
|
||||
// List of all variables that have to be updated regardless if they are linked to an item
|
||||
public final static List<String> ALWAYS_UPDATE_VARIABLES = Arrays.asList(
|
||||
HeliosEasyControlsBindingConstants.DATE_FORMAT, HeliosEasyControlsBindingConstants.DATE,
|
||||
HeliosEasyControlsBindingConstants.TIME, HeliosEasyControlsBindingConstants.TIME_ZONE_DIFFERENCE_TO_GMT,
|
||||
HeliosEasyControlsBindingConstants.BYPASS_FROM_DAY, HeliosEasyControlsBindingConstants.BYPASS_FROM_MONTH,
|
||||
HeliosEasyControlsBindingConstants.BYPASS_TO_DAY, HeliosEasyControlsBindingConstants.BYPASS_TO_MONTH);
|
||||
|
||||
// List of all properties
|
||||
public final static List<String> PROPERTY_NAMES = Arrays.asList(
|
||||
HeliosEasyControlsBindingConstants.ARTICLE_DESCRIPTION, HeliosEasyControlsBindingConstants.REF_NO,
|
||||
HeliosEasyControlsBindingConstants.SER_NO, HeliosEasyControlsBindingConstants.PROD_CODE,
|
||||
HeliosEasyControlsBindingConstants.MAC_ADDRESS, HeliosEasyControlsBindingConstants.SOFTWARE_VERSION_BASIS,
|
||||
HeliosEasyControlsBindingConstants.DATE_FORMAT, HeliosEasyControlsBindingConstants.LANGUAGE,
|
||||
HeliosEasyControlsBindingConstants.UNIT_CONFIG, HeliosEasyControlsBindingConstants.KWL_BE,
|
||||
HeliosEasyControlsBindingConstants.KWL_BEC, HeliosEasyControlsBindingConstants.EXTERNAL_CONTACT,
|
||||
HeliosEasyControlsBindingConstants.FUNCTION_TYPE_KWL_EM,
|
||||
HeliosEasyControlsBindingConstants.HEAT_EXCHANGER_TYPE,
|
||||
HeliosEasyControlsBindingConstants.OFFSET_EXTRACT_AIR,
|
||||
HeliosEasyControlsBindingConstants.ASSIGNMENT_FAN_STAGES,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_1_EXTRACT_AIR,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_2_EXTRACT_AIR,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_3_EXTRACT_AIR,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_4_EXTRACT_AIR,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_1_SUPPLY_AIR,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_2_SUPPLY_AIR,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_3_SUPPLY_AIR,
|
||||
HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_4_SUPPLY_AIR,
|
||||
HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_0TO2V,
|
||||
HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_2TO4V,
|
||||
HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_4TO6V,
|
||||
HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_6TO8V,
|
||||
HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_8TO10V, HeliosEasyControlsBindingConstants.VHZ_TYPE,
|
||||
HeliosEasyControlsBindingConstants.HUMIDITY_CONTROL_STATUS,
|
||||
HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_0, HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_1,
|
||||
HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_2, HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_3,
|
||||
HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_4, HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_5,
|
||||
HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_6, HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_7,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_1,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_2,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_3,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_4,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_5,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_6,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_7,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_8,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_1,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_2,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_3,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_4,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_5,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_6,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_7,
|
||||
HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_8,
|
||||
HeliosEasyControlsBindingConstants.CO2_CONTROL_STATUS,
|
||||
HeliosEasyControlsBindingConstants.VOC_CONTROL_STATUS);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.modbus.helioseasycontrols.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link HeliosEasyControlsConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Bernhard Bauer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeliosEasyControlsConfiguration {
|
||||
|
||||
/**
|
||||
* The binding's refresh interval
|
||||
*/
|
||||
private int refreshInterval;
|
||||
|
||||
public int getRefreshInterval() {
|
||||
return refreshInterval;
|
||||
}
|
||||
|
||||
public void setRefreshInterval(int refreshInterval) {
|
||||
this.refreshInterval = refreshInterval;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,791 @@
|
||||
/**
|
||||
* 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.modbus.helioseasycontrols.internal;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.modbus.handler.ModbusEndpointThingHandler;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.SmartHomeUnits;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Channel;
|
||||
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.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.io.transport.modbus.ModbusBitUtilities;
|
||||
import org.openhab.io.transport.modbus.ModbusCommunicationInterface;
|
||||
import org.openhab.io.transport.modbus.ModbusReadFunctionCode;
|
||||
import org.openhab.io.transport.modbus.ModbusReadRequestBlueprint;
|
||||
import org.openhab.io.transport.modbus.ModbusRegister;
|
||||
import org.openhab.io.transport.modbus.ModbusRegisterArray;
|
||||
import org.openhab.io.transport.modbus.ModbusWriteRegisterRequestBlueprint;
|
||||
import org.openhab.io.transport.modbus.endpoint.ModbusSlaveEndpoint;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* The {@link HeliosEasyControlsHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Bernhard Bauer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeliosEasyControlsHandler extends BaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HeliosEasyControlsHandler.class);
|
||||
|
||||
private @Nullable HeliosEasyControlsConfiguration config;
|
||||
|
||||
private @Nullable ScheduledFuture<?> pollingJob;
|
||||
|
||||
private @Nullable Map<String, HeliosVariable> variableMap;
|
||||
|
||||
/**
|
||||
* This flag is used to ensure read requests (consisting of a write and subsequent read) are not influenced by
|
||||
* another transaction
|
||||
*/
|
||||
private final Map<ModbusSlaveEndpoint, Semaphore> transactionLocks = new ConcurrentHashMap<>();
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
private @Nullable ModbusCommunicationInterface comms;
|
||||
|
||||
private int dateFormat = -1;
|
||||
private ZonedDateTime sysDate = ZonedDateTime.now(); // initialize with local system time as a best guess
|
||||
// before reading from device
|
||||
|
||||
private class BypassDate {
|
||||
// initialization to avoid issues when updating before all variables were read
|
||||
private int month = 1;
|
||||
private int day = 1;
|
||||
|
||||
public void setMonth(int month) {
|
||||
this.month = month;
|
||||
}
|
||||
|
||||
public void setDay(int day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
public DateTimeType toDateTimeType() {
|
||||
return new DateTimeType(ZonedDateTime.of(1900, this.month, this.day, 0, 0, 0, 0, ZoneId.of("UTC+00:00")));
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable BypassDate bypassFrom, bypassTo;
|
||||
|
||||
public HeliosEasyControlsHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads variable definitions from JSON file and store them in variableMap
|
||||
*/
|
||||
private void readVariableDefinition() {
|
||||
Type vMapType = new TypeToken<Map<String, HeliosVariable>>() {
|
||||
}.getType();
|
||||
try (InputStreamReader jsonFile = new InputStreamReader(
|
||||
getClass().getResourceAsStream(HeliosEasyControlsBindingConstants.VARIABLES_DEFINITION_FILE));
|
||||
BufferedReader reader = new BufferedReader(jsonFile)) {
|
||||
this.variableMap = gson.fromJson(reader, vMapType);
|
||||
} catch (IOException e) {
|
||||
this.handleError("Error reading variable definition file", ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
if (variableMap != null) {
|
||||
// add the name to the variable itself
|
||||
for (Map.Entry<String, HeliosVariable> entry : this.variableMap.entrySet()) {
|
||||
entry.getValue().setName(entry.getKey()); // workaround to set the variable name inside the
|
||||
// HeliosVariable object
|
||||
if (!entry.getValue().isOk()) {
|
||||
this.handleError("Variables definition file contains inconsistent data",
|
||||
ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.handleError("Variables definition file not found or of illegal format",
|
||||
ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the endpoint handler from the bridge this handler is connected to
|
||||
* Checks that we're connected to the right type of bridge
|
||||
*
|
||||
* @return the endpoint handler or null if the bridge does not exist
|
||||
*/
|
||||
private @Nullable ModbusEndpointThingHandler getEndpointThingHandler() {
|
||||
Bridge bridge = getBridge();
|
||||
if (bridge == null) {
|
||||
logger.debug("Bridge is null");
|
||||
return null;
|
||||
}
|
||||
if (bridge.getStatus() != ThingStatus.ONLINE) {
|
||||
logger.debug("Bridge is not online");
|
||||
return null;
|
||||
}
|
||||
|
||||
ThingHandler handler = bridge.getHandler();
|
||||
if (handler == null) {
|
||||
logger.debug("Bridge handler is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (handler instanceof ModbusEndpointThingHandler) {
|
||||
return (ModbusEndpointThingHandler) handler;
|
||||
} else {
|
||||
logger.debug("Unexpected bridge handler: {}", handler);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the modbus endpoint
|
||||
*/
|
||||
private void connectEndpoint() {
|
||||
if (this.comms != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModbusEndpointThingHandler slaveEndpointThingHandler = getEndpointThingHandler();
|
||||
if (slaveEndpointThingHandler == null) {
|
||||
@SuppressWarnings("null")
|
||||
String label = Optional.ofNullable(getBridge()).map(b -> b.getLabel()).orElse("<null>");
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
|
||||
String.format("Bridge '%s' is offline", label));
|
||||
logger.debug("No bridge handler available -- aborting init for {}", label);
|
||||
return;
|
||||
}
|
||||
|
||||
comms = slaveEndpointThingHandler.getCommunicationInterface();
|
||||
|
||||
if (comms == null) {
|
||||
@SuppressWarnings("null")
|
||||
String label = Optional.ofNullable(getBridge()).map(b -> b.getLabel()).orElse("<null>");
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
|
||||
String.format("Bridge '%s' not completely initialized", label));
|
||||
logger.debug("Bridge not initialized fully (no endpoint) -- aborting init for {}", this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
this.config = getConfigAs(HeliosEasyControlsConfiguration.class);
|
||||
this.readVariableDefinition();
|
||||
this.connectEndpoint();
|
||||
if ((this.comms != null) && (this.variableMap != null) && (this.config != null)) {
|
||||
this.transactionLocks.putIfAbsent(this.comms.getEndpoint(), new Semaphore(1, true));
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
// background initialization
|
||||
scheduler.execute(() -> {
|
||||
readValue(HeliosEasyControlsBindingConstants.DATE_FORMAT);
|
||||
// status will be updated to ONLINE by the read callback function (via processResponse)
|
||||
});
|
||||
|
||||
// poll for status updates regularly
|
||||
HeliosEasyControlsConfiguration config = this.config;
|
||||
if (config != null) {
|
||||
this.pollingJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||
if (variableMap != null) {
|
||||
for (Map.Entry<String, HeliosVariable> entry : variableMap.entrySet()) {
|
||||
if (this.isProperty(entry.getKey()) || isLinked(entry.getValue().getGroupAndName())
|
||||
|| HeliosEasyControlsBindingConstants.ALWAYS_UPDATE_VARIABLES
|
||||
.contains(entry.getKey())) {
|
||||
readValue(entry.getKey());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleError("Variable definition is null", ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
}, config.getRefreshInterval(), config.getRefreshInterval(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
} else { // at least one null assertion has failed, let's log the problem and update the thing status
|
||||
if (this.comms == null) {
|
||||
this.handleError("Modbus communication interface is unavailable",
|
||||
ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
}
|
||||
if (this.variableMap == null) {
|
||||
this.handleError("Variable definition is unavailable", ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
if (this.config == null) {
|
||||
this.handleError("Binding configuration is unavailable", ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (this.pollingJob != null) {
|
||||
this.pollingJob.cancel(true);
|
||||
}
|
||||
this.comms = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
String channelId = channelUID.getIdWithoutGroup();
|
||||
if (command instanceof RefreshType) {
|
||||
if (channelId.equals(HeliosEasyControlsBindingConstants.SYS_DATE)) {
|
||||
scheduler.submit(() -> readValue(HeliosEasyControlsBindingConstants.DATE));
|
||||
scheduler.submit(() -> readValue(HeliosEasyControlsBindingConstants.TIME));
|
||||
} else if (channelId.equals(HeliosEasyControlsBindingConstants.BYPASS_FROM)) {
|
||||
scheduler.submit(() -> readValue(HeliosEasyControlsBindingConstants.BYPASS_FROM_DAY));
|
||||
scheduler.submit(() -> readValue(HeliosEasyControlsBindingConstants.BYPASS_FROM_MONTH));
|
||||
} else if (channelId.equals(HeliosEasyControlsBindingConstants.BYPASS_TO)) {
|
||||
scheduler.submit(() -> readValue(HeliosEasyControlsBindingConstants.BYPASS_TO_DAY));
|
||||
scheduler.submit(() -> readValue(HeliosEasyControlsBindingConstants.BYPASS_TO_MONTH));
|
||||
} else {
|
||||
scheduler.submit(() -> readValue(channelId));
|
||||
}
|
||||
} else { // write command
|
||||
String value = null;
|
||||
if (command instanceof OnOffType) {
|
||||
value = command == OnOffType.ON ? "1" : "0";
|
||||
} else if (command instanceof DateTimeType) {
|
||||
ZonedDateTime d = ((DateTimeType) command).getZonedDateTime();
|
||||
if (channelId.equals(HeliosEasyControlsBindingConstants.SYS_DATE)) {
|
||||
setSysDateTime(d);
|
||||
} else if (channelId.equals(HeliosEasyControlsBindingConstants.BYPASS_FROM)) {
|
||||
this.setBypass(true, d.getDayOfMonth(), d.getMonthValue());
|
||||
} else if (channelId.equals(HeliosEasyControlsBindingConstants.BYPASS_TO)) {
|
||||
this.setBypass(false, d.getDayOfMonth(), d.getMonthValue());
|
||||
} else {
|
||||
value = formatDate(channelId, ((DateTimeType) command).getZonedDateTime());
|
||||
}
|
||||
} else if ((command instanceof DecimalType) || (command instanceof StringType)) {
|
||||
value = command.toString();
|
||||
} else if (command instanceof QuantityType<?>) {
|
||||
// convert item's unit to the Helios device's unit
|
||||
Map<String, HeliosVariable> variableMap = this.variableMap;
|
||||
if (variableMap != null) {
|
||||
String unit = variableMap.get(channelId).getUnit();
|
||||
QuantityType<?> val = (QuantityType<?>) command;
|
||||
if (unit != null) {
|
||||
switch (unit) {
|
||||
case HeliosVariable.UNIT_DAY:
|
||||
val = val.toUnit(SmartHomeUnits.DAY);
|
||||
break;
|
||||
case HeliosVariable.UNIT_HOUR:
|
||||
val = val.toUnit(SmartHomeUnits.HOUR);
|
||||
break;
|
||||
case HeliosVariable.UNIT_MIN:
|
||||
val = val.toUnit(SmartHomeUnits.MINUTE);
|
||||
break;
|
||||
case HeliosVariable.UNIT_SEC:
|
||||
val = val.toUnit(SmartHomeUnits.SECOND);
|
||||
break;
|
||||
case HeliosVariable.UNIT_VOLT:
|
||||
val = val.toUnit(SmartHomeUnits.VOLT);
|
||||
break;
|
||||
case HeliosVariable.UNIT_PERCENT:
|
||||
val = val.toUnit(SmartHomeUnits.PERCENT);
|
||||
break;
|
||||
case HeliosVariable.UNIT_PPM:
|
||||
val = val.toUnit(SmartHomeUnits.PARTS_PER_MILLION);
|
||||
break;
|
||||
case HeliosVariable.UNIT_TEMP:
|
||||
val = val.toUnit(SIUnits.CELSIUS);
|
||||
break;
|
||||
}
|
||||
value = val != null ? String.valueOf(val.doubleValue()) : null; // ignore the UoM
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != null) {
|
||||
final String v = value;
|
||||
scheduler.submit(() -> {
|
||||
try {
|
||||
writeValue(channelId, v);
|
||||
if (variableMap != null) {
|
||||
updateState(variableMap.get(channelId), v);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
} catch (HeliosException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Writing value " + v + "to channel " + channelId + " failed: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return Collections.singleton(HeliosEasyControlsActions.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the provided variable name is a property
|
||||
*
|
||||
* @param variableName The variable's name
|
||||
* @return true if the variable is a property
|
||||
*/
|
||||
private boolean isProperty(String variableName) {
|
||||
return HeliosEasyControlsBindingConstants.PROPERTY_NAMES.contains(variableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a variable value to the Helios device
|
||||
*
|
||||
* @param variableName The variable name
|
||||
* @param value The new value
|
||||
* @return The value if the transaction succeeded, <tt>null</tt> otherwise
|
||||
* @throws HeliosException Thrown if the variable is read-only or the provided value is out of range
|
||||
*/
|
||||
public void writeValue(String variableName, String value) throws HeliosException {
|
||||
if (this.variableMap == null) {
|
||||
this.handleError("Variable definition is unavailable.", ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
return;
|
||||
} else {
|
||||
Map<String, HeliosVariable> variableMap = this.variableMap;
|
||||
if (variableMap != null) {
|
||||
HeliosVariable v = variableMap.get(variableName);
|
||||
|
||||
if (!v.hasWriteAccess()) {
|
||||
throw new HeliosException("Variable " + variableName + " is read-only");
|
||||
} else if (!v.isInAllowedRange(value)) {
|
||||
throw new HeliosException(
|
||||
"Value " + value + " is outside of allowed range of variable " + variableName);
|
||||
} else if (this.comms != null) {
|
||||
// write to device
|
||||
String payload = v.getVariableString() + "=" + value;
|
||||
ModbusCommunicationInterface comms = this.comms;
|
||||
if (comms != null) {
|
||||
final Semaphore lock = transactionLocks.get(comms.getEndpoint());
|
||||
try {
|
||||
lock.acquire();
|
||||
comms.submitOneTimeWrite(
|
||||
new ModbusWriteRegisterRequestBlueprint(HeliosEasyControlsBindingConstants.UNIT_ID,
|
||||
HeliosEasyControlsBindingConstants.START_ADDRESS,
|
||||
new ModbusRegisterArray(preparePayload(payload)), true,
|
||||
HeliosEasyControlsBindingConstants.MAX_TRIES),
|
||||
result -> {
|
||||
lock.release();
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}, failureInfo -> {
|
||||
lock.release();
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Error writing to device: " + failureInfo.getCause().getMessage());
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn(
|
||||
"{} encountered Exception when trying to lock Semaphore for writing variable {} to the device: {}",
|
||||
HeliosEasyControlsHandler.class.getSimpleName(), variableName, e.getMessage());
|
||||
}
|
||||
}
|
||||
} else { // comms is null
|
||||
this.handleError("Modbus communication interface is null", ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a variable from the Helios device
|
||||
*
|
||||
* @param variableName The variable name
|
||||
* @return The value
|
||||
*/
|
||||
public void readValue(String variableName) {
|
||||
Map<String, HeliosVariable> variableMap = this.variableMap;
|
||||
ModbusCommunicationInterface comms = this.comms;
|
||||
if ((comms != null) && (variableMap != null)) {
|
||||
final Semaphore lock = transactionLocks.get(comms.getEndpoint());
|
||||
HeliosVariable v = variableMap.get(variableName);
|
||||
if (v.hasReadAccess()) {
|
||||
try {
|
||||
lock.acquire(); // will block until lock is available
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn("{} encountered Exception when trying to read variable {} from the device: {}",
|
||||
HeliosEasyControlsHandler.class.getSimpleName(), variableName, e.getMessage());
|
||||
return;
|
||||
}
|
||||
// write variable name to register
|
||||
String payload = v.getVariableString();
|
||||
comms.submitOneTimeWrite(new ModbusWriteRegisterRequestBlueprint(
|
||||
HeliosEasyControlsBindingConstants.UNIT_ID, HeliosEasyControlsBindingConstants.START_ADDRESS,
|
||||
new ModbusRegisterArray(preparePayload(payload)), true,
|
||||
HeliosEasyControlsBindingConstants.MAX_TRIES), result -> {
|
||||
comms.submitOneTimePoll(
|
||||
new ModbusReadRequestBlueprint(HeliosEasyControlsBindingConstants.UNIT_ID,
|
||||
ModbusReadFunctionCode.READ_MULTIPLE_REGISTERS,
|
||||
HeliosEasyControlsBindingConstants.START_ADDRESS, v.getCount(),
|
||||
HeliosEasyControlsBindingConstants.MAX_TRIES),
|
||||
pollResult -> {
|
||||
lock.release();
|
||||
Optional<ModbusRegisterArray> registers = pollResult.getRegisters();
|
||||
if (registers.isPresent()) {
|
||||
processResponse(v, registers.get());
|
||||
}
|
||||
}, failureInfo -> {
|
||||
lock.release();
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Error reading from device: " + failureInfo.getCause().getMessage());
|
||||
});
|
||||
}, failureInfo -> {
|
||||
lock.release();
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Error writing to device: " + failureInfo.getCause().getMessage());
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
if (this.comms == null) {
|
||||
this.handleError("Modbus communication interface is unavailable",
|
||||
ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
}
|
||||
if (variableMap == null) {
|
||||
this.handleError("Variable definition is unavailable", ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSysDate(DateTimeType dateTime) {
|
||||
this.updateSysDateTime(dateTime.getZonedDateTime(), true, sysDate.getOffset().getTotalSeconds() / 60 / 60);
|
||||
}
|
||||
|
||||
private void updateSysTime(DateTimeType dateTime) {
|
||||
this.updateSysDateTime(dateTime.getZonedDateTime(), false, sysDate.getOffset().getTotalSeconds() / 60 / 60);
|
||||
}
|
||||
|
||||
private void updateUtcOffset(int utcOffset) {
|
||||
this.updateSysDateTime(this.sysDate, true, sysDate.getOffset().getTotalSeconds() / 60 / 60);
|
||||
}
|
||||
|
||||
private void updateSysDateTime(ZonedDateTime dateTime, boolean updateDate, int utcOffset) {
|
||||
ZonedDateTime sysDate = this.sysDate;
|
||||
sysDate = ZonedDateTime.of(updateDate ? dateTime.getYear() : sysDate.getYear(),
|
||||
updateDate ? dateTime.getMonthValue() : sysDate.getMonthValue(),
|
||||
updateDate ? dateTime.getDayOfMonth() : sysDate.getDayOfMonth(),
|
||||
updateDate ? sysDate.getHour() : dateTime.getHour(),
|
||||
updateDate ? sysDate.getMinute() : dateTime.getMinute(),
|
||||
updateDate ? sysDate.getSecond() : dateTime.getSecond(), 0,
|
||||
ZoneId.of("UTC" + (utcOffset >= 0 ? "+" : "") + String.format("%02d", utcOffset) + ":00"));
|
||||
updateState("general#" + HeliosEasyControlsBindingConstants.SYS_DATE, new DateTimeType(sysDate));
|
||||
this.sysDate = sysDate;
|
||||
}
|
||||
|
||||
private void setSysDateTime(ZonedDateTime date) {
|
||||
try {
|
||||
this.writeValue(HeliosEasyControlsBindingConstants.DATE,
|
||||
this.formatDate(HeliosEasyControlsBindingConstants.DATE, date));
|
||||
this.writeValue(HeliosEasyControlsBindingConstants.TIME,
|
||||
date.getHour() + ":" + date.getMinute() + ":" + date.getSecond());
|
||||
this.writeValue(HeliosEasyControlsBindingConstants.TIME_ZONE_DIFFERENCE_TO_GMT,
|
||||
Integer.toString(date.getOffset().getTotalSeconds() / 60 / 60));
|
||||
} catch (HeliosException e) {
|
||||
logger.warn("{} encountered Exception when trying to set system date: {}",
|
||||
HeliosEasyControlsHandler.class.getSimpleName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected void setSysDateTime() {
|
||||
this.setSysDateTime(ZonedDateTime.now());
|
||||
}
|
||||
|
||||
private void updateBypass(boolean from, boolean month, int val) {
|
||||
BypassDate bypassDate = from ? this.bypassFrom : this.bypassTo;
|
||||
if (bypassDate == null) {
|
||||
bypassDate = new BypassDate();
|
||||
}
|
||||
if (month) {
|
||||
bypassDate.setMonth(val);
|
||||
|
||||
} else {
|
||||
bypassDate.setDay(val);
|
||||
}
|
||||
updateState("unitConfig#" + (from ? HeliosEasyControlsBindingConstants.BYPASS_FROM
|
||||
: HeliosEasyControlsBindingConstants.BYPASS_TO), bypassDate.toDateTimeType());
|
||||
if (from) {
|
||||
this.bypassFrom = bypassDate;
|
||||
|
||||
} else {
|
||||
this.bypassTo = bypassDate;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setBypass(boolean from, int day, int month) {
|
||||
try {
|
||||
this.writeValue(from ? HeliosEasyControlsBindingConstants.BYPASS_FROM_DAY
|
||||
: HeliosEasyControlsBindingConstants.BYPASS_TO_DAY, Integer.toString(day));
|
||||
this.writeValue(from ? HeliosEasyControlsBindingConstants.BYPASS_FROM_MONTH
|
||||
: HeliosEasyControlsBindingConstants.BYPASS_TO_MONTH, Integer.toString(month));
|
||||
} catch (HeliosException e) {
|
||||
logger.warn("{} encountered Exception when trying to set bypass period: {}",
|
||||
HeliosEasyControlsHandler.class.getSimpleName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the provided date to a string in the device's configured date format
|
||||
*
|
||||
* @param variableName the variable name
|
||||
* @param date the date to be formatted
|
||||
* @return a string in the device's configured date format
|
||||
*/
|
||||
public String formatDate(String variableName, ZonedDateTime date) {
|
||||
String y = Integer.toString(date.getYear());
|
||||
String m = Integer.toString(date.getMonthValue());
|
||||
if (m.length() == 1) {
|
||||
m = "0" + m;
|
||||
}
|
||||
String d = Integer.toString(date.getDayOfMonth());
|
||||
if (d.length() == 1) {
|
||||
d = "0" + d;
|
||||
}
|
||||
if (variableName.equals(HeliosEasyControlsBindingConstants.DATE)) { // fixed format for writing the system date
|
||||
return d + "." + m + "." + y;
|
||||
} else {
|
||||
switch (this.dateFormat) {
|
||||
case 0: // dd.mm.yyyy
|
||||
return d + "." + m + "." + y;
|
||||
case 1: // mm.dd.yyyy
|
||||
return m + "." + d + "." + y;
|
||||
case 2: // yyyy.mm.dd
|
||||
return y + "." + m + "." + d;
|
||||
default:
|
||||
return d + "." + m + "." + y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DateTimeType object based on the provided String and the device's configured date format
|
||||
*
|
||||
* @param date The date string read from the device
|
||||
* @return A DateTimeType object representing the date or time specified
|
||||
*/
|
||||
private DateTimeType toDateTime(String date) {
|
||||
String[] dateTimeParts = null;
|
||||
String dateTime = date;
|
||||
dateTimeParts = date.split("\\."); // try to split date components
|
||||
if (dateTimeParts.length == 1) { // time
|
||||
return DateTimeType.valueOf(date);
|
||||
} else if (dateTimeParts.length == 3) { // date - we'll try the device's date format
|
||||
switch (this.dateFormat) {
|
||||
case 0: // dd.mm.yyyy
|
||||
dateTime = dateTimeParts[2] + "-" + dateTimeParts[1] + "-" + dateTimeParts[0];
|
||||
break;
|
||||
case 1: // mm.dd.yyyy
|
||||
dateTime = dateTimeParts[2] + "-" + dateTimeParts[0] + "-" + dateTimeParts[1];
|
||||
break;
|
||||
case 2: // yyyy.mm.dd
|
||||
dateTime = dateTimeParts[0] + "-" + dateTimeParts[1] + "-" + dateTimeParts[2];
|
||||
break;
|
||||
default:
|
||||
dateTime = dateTimeParts[2] + "-" + dateTimeParts[1] + "-" + dateTimeParts[0];
|
||||
break;
|
||||
}
|
||||
return DateTimeType.valueOf(dateTime);
|
||||
}
|
||||
// falling back to default date format (apparently using the configured format has failed)
|
||||
dateTime = dateTimeParts[2] + "-" + dateTimeParts[1] + "-" + dateTimeParts[0];
|
||||
return DateTimeType.valueOf(dateTime);
|
||||
}
|
||||
|
||||
private @Nullable QuantityType<?> toQuantityType(String value, @Nullable String unit) {
|
||||
if (unit == null) {
|
||||
return null;
|
||||
} else if (unit.equals(HeliosVariable.UNIT_DAY)) {
|
||||
return new QuantityType<>(Integer.parseInt(value), SmartHomeUnits.DAY);
|
||||
} else if (unit.equals(HeliosVariable.UNIT_HOUR)) {
|
||||
return new QuantityType<>(Integer.parseInt(value), SmartHomeUnits.HOUR);
|
||||
} else if (unit.equals(HeliosVariable.UNIT_MIN)) {
|
||||
return new QuantityType<>(Integer.parseInt(value), SmartHomeUnits.MINUTE);
|
||||
} else if (unit.equals(HeliosVariable.UNIT_SEC)) {
|
||||
return new QuantityType<>(Integer.parseInt(value), SmartHomeUnits.SECOND);
|
||||
} else if (unit.equals(HeliosVariable.UNIT_VOLT)) {
|
||||
return new QuantityType<>(Float.parseFloat(value), SmartHomeUnits.VOLT);
|
||||
} else if (unit.equals(HeliosVariable.UNIT_PERCENT)) {
|
||||
return new QuantityType<>(Float.parseFloat(value), SmartHomeUnits.PERCENT);
|
||||
} else if (unit.equals(HeliosVariable.UNIT_PPM)) {
|
||||
return new QuantityType<>(Float.parseFloat(value), SmartHomeUnits.PARTS_PER_MILLION);
|
||||
} else if (unit.equals(HeliosVariable.UNIT_TEMP)) {
|
||||
return new QuantityType<>(Float.parseFloat(value), SIUnits.CELSIUS);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the payload for the request
|
||||
*
|
||||
* @param payload The String representation of the payload
|
||||
* @return The Register representation of the payload
|
||||
*/
|
||||
private ModbusRegister[] preparePayload(String payload) {
|
||||
|
||||
// determine number of registers
|
||||
int l = (payload.length() + 1) / 2; // +1 because we need to include at least one termination symbol 0x00
|
||||
if ((payload.length() + 1) % 2 != 0) {
|
||||
l++;
|
||||
}
|
||||
|
||||
ModbusRegister reg[] = new ModbusRegister[l];
|
||||
byte[] b = payload.getBytes();
|
||||
int ch = 0;
|
||||
for (int i = 0; i < reg.length; i++) {
|
||||
byte b1 = ch < b.length ? b[ch] : (byte) 0x00; // terminate with 0x00 if at the end of the payload
|
||||
ch++;
|
||||
byte b2 = ch < b.length ? b[ch] : (byte) 0x00;
|
||||
ch++;
|
||||
reg[i] = new ModbusRegister(b1, b2);
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the Helios device' response and updates the channel with the actual value of the variable
|
||||
*
|
||||
* @param response The registers received from the Helios device
|
||||
* @return The value or <tt>null</tt> if an error occurred
|
||||
*/
|
||||
private void processResponse(HeliosVariable v, ModbusRegisterArray registers) {
|
||||
String r = ModbusBitUtilities
|
||||
.extractStringFromRegisters(registers, 0, registers.size() * 2, StandardCharsets.US_ASCII).toString();
|
||||
String[] parts = r.split("=", 2); // remove the part "vXXXX=" from the string
|
||||
// making sure we have a proper response and the response matches the requested variable
|
||||
if ((parts.length == 2) && (v.getVariableString().equals(parts[0]))) {
|
||||
if (this.isProperty(v.getName())) {
|
||||
try {
|
||||
updateProperty(v.getName(), v.formatPropertyValue(parts[1]));
|
||||
} catch (HeliosException e) {
|
||||
logger.warn("{} encountered Exception when trying to update property: {}",
|
||||
HeliosEasyControlsHandler.class.getSimpleName(), e.getMessage());
|
||||
}
|
||||
} else {
|
||||
this.updateState(v, parts[1]);
|
||||
}
|
||||
} else { // another variable was read
|
||||
logger.warn("{} tried to read value from variable {} and the result provided by the device was {}",
|
||||
HeliosEasyControlsHandler.class.getSimpleName(), v.getName(), r);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateState(HeliosVariable v, String value) {
|
||||
String variableType = v.getType();
|
||||
// System date and time
|
||||
if (v.getName().equals(HeliosEasyControlsBindingConstants.DATE)) {
|
||||
this.updateSysDate(this.toDateTime(value));
|
||||
} else if (v.getName().equals(HeliosEasyControlsBindingConstants.TIME)) {
|
||||
this.updateSysTime(this.toDateTime(value));
|
||||
} else if (v.getName().equals(HeliosEasyControlsBindingConstants.TIME_ZONE_DIFFERENCE_TO_GMT)) {
|
||||
this.updateUtcOffset(Integer.parseInt(value));
|
||||
// Bypass
|
||||
} else if (v.getName().equals(HeliosEasyControlsBindingConstants.BYPASS_FROM_DAY)) {
|
||||
this.updateBypass(true, false, Integer.parseInt(value));
|
||||
} else if (v.getName().equals(HeliosEasyControlsBindingConstants.BYPASS_FROM_MONTH)) {
|
||||
this.updateBypass(true, true, Integer.parseInt(value));
|
||||
} else if (v.getName().equals(HeliosEasyControlsBindingConstants.BYPASS_TO_DAY)) {
|
||||
this.updateBypass(false, false, Integer.parseInt(value));
|
||||
} else if (v.getName().equals(HeliosEasyControlsBindingConstants.BYPASS_TO_MONTH)) {
|
||||
this.updateBypass(false, true, Integer.parseInt(value));
|
||||
} else {
|
||||
Channel channel = getThing().getChannel(v.getGroupAndName());
|
||||
String itemType;
|
||||
if (channel != null) {
|
||||
itemType = channel.getAcceptedItemType();
|
||||
if (itemType != null) {
|
||||
if (itemType.startsWith("Number:")) {
|
||||
itemType = "Number";
|
||||
}
|
||||
switch (itemType) {
|
||||
case "Number":
|
||||
if (((variableType.equals(HeliosVariable.TYPE_INTEGER))
|
||||
|| (variableType == HeliosVariable.TYPE_FLOAT)) && (!value.equals("-"))) {
|
||||
State state = null;
|
||||
if (v.getUnit() == null) {
|
||||
state = DecimalType.valueOf(value);
|
||||
} else { // QuantityType
|
||||
state = this.toQuantityType(value, v.getUnit());
|
||||
}
|
||||
if (state != null) {
|
||||
updateState(v.getGroupAndName(), state);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
// update date format and UTC offset upon read
|
||||
if (v.getName().equals(HeliosEasyControlsBindingConstants.DATE_FORMAT)) {
|
||||
this.dateFormat = Integer.parseInt(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Switch":
|
||||
if (variableType.equals(HeliosVariable.TYPE_INTEGER)) {
|
||||
updateState(v.getGroupAndName(), value.equals("1") ? OnOffType.ON : OnOffType.OFF);
|
||||
}
|
||||
break;
|
||||
case "String":
|
||||
if (variableType.equals(HeliosVariable.TYPE_STRING)) {
|
||||
updateState(v.getGroupAndName(), StringType.valueOf(value));
|
||||
}
|
||||
break;
|
||||
case "DateTime":
|
||||
if (variableType.equals(HeliosVariable.TYPE_STRING)) {
|
||||
updateState(v.getGroupAndName(), toDateTime(value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else { // itemType was null
|
||||
logger.warn("{} couldn't determine item type of variable {}",
|
||||
HeliosEasyControlsHandler.class.getSimpleName(), v.getName());
|
||||
}
|
||||
} else { // channel was null
|
||||
logger.warn("{} couldn't find channel for variable {}", HeliosEasyControlsHandler.class.getSimpleName(),
|
||||
v.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an error (as a warning entry) and updates the thing status
|
||||
*
|
||||
* @param errorMsg The error message to be logged and provided with the Thing's status update
|
||||
* @param status The Thing's new status
|
||||
*/
|
||||
private void handleError(String errorMsg, ThingStatusDetail status) {
|
||||
updateStatus(ThingStatus.OFFLINE, status, errorMsg);
|
||||
}
|
||||
}
|
||||
@@ -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.modbus.helioseasycontrols.internal;
|
||||
|
||||
import static org.openhab.binding.modbus.helioseasycontrols.internal.HeliosEasyControlsBindingConstants.THING_TYPE_HELIOS_VENTILATION_EASY_CONTROLS;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
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.Component;
|
||||
|
||||
/**
|
||||
* The {@link HeliosEasyControlsHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Bernhard Bauer - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.helioseasycontrols", service = ThingHandlerFactory.class)
|
||||
public class HeliosEasyControlsHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
|
||||
.singleton(THING_TYPE_HELIOS_VENTILATION_EASY_CONTROLS);
|
||||
|
||||
@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 (THING_TYPE_HELIOS_VENTILATION_EASY_CONTROLS.equals(thingTypeUID)) {
|
||||
return new HeliosEasyControlsHandler(thing);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.modbus.helioseasycontrols.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* This class represents an exception specific to the HeliosEasyControls protocol.
|
||||
*
|
||||
* @author Bernhard Bauer - Initial contribution
|
||||
* @version 2.0
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeliosException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -7256846679824295950L;
|
||||
|
||||
public HeliosException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,531 @@
|
||||
/**
|
||||
* 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.modbus.helioseasycontrols.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class represents a variable of the Helios modbus.
|
||||
*
|
||||
* @author Bernhard Bauer - Initial contribution
|
||||
* @version 2.0
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeliosVariable implements Comparable<HeliosVariable> {
|
||||
|
||||
/**
|
||||
* Read access
|
||||
*/
|
||||
public static final String ACCESS_R = "R";
|
||||
|
||||
/**
|
||||
* Write access
|
||||
*/
|
||||
public static final String ACCESS_W = "W";
|
||||
|
||||
/**
|
||||
* Read and write access
|
||||
*/
|
||||
public static final String ACCESS_RW = "RW";
|
||||
|
||||
/**
|
||||
* Integer type
|
||||
*/
|
||||
public static final String TYPE_INTEGER = "int";
|
||||
|
||||
/**
|
||||
* Float type
|
||||
*/
|
||||
public static final String TYPE_FLOAT = "float";
|
||||
|
||||
/**
|
||||
* String type
|
||||
*/
|
||||
public static final String TYPE_STRING = "string";
|
||||
|
||||
/**
|
||||
* Unit Volt
|
||||
*/
|
||||
public static final String UNIT_VOLT = "V";
|
||||
|
||||
/**
|
||||
* Unit %
|
||||
*/
|
||||
public static final String UNIT_PERCENT = "%";
|
||||
|
||||
/**
|
||||
* Unit ppm
|
||||
*/
|
||||
public static final String UNIT_PPM = "ppm";
|
||||
|
||||
/**
|
||||
* Unit degrees Celsius
|
||||
*/
|
||||
public static final String UNIT_TEMP = "°C";
|
||||
|
||||
/**
|
||||
* Unit day
|
||||
*/
|
||||
public static final String UNIT_DAY = "d";
|
||||
|
||||
/**
|
||||
* Unit hour
|
||||
*/
|
||||
public static final String UNIT_HOUR = "h";
|
||||
|
||||
/**
|
||||
* Unit minute
|
||||
*/
|
||||
public static final String UNIT_MIN = "min";
|
||||
|
||||
/**
|
||||
* Unit second
|
||||
*/
|
||||
public static final String UNIT_SEC = "s";
|
||||
|
||||
/**
|
||||
* The variable number
|
||||
*/
|
||||
private int variable;
|
||||
|
||||
/**
|
||||
* The variable name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The variable group
|
||||
*/
|
||||
private @Nullable String group;
|
||||
|
||||
/**
|
||||
* The access to the variable
|
||||
*/
|
||||
private String access;
|
||||
|
||||
/**
|
||||
* The length of the variable (number of chars)
|
||||
*/
|
||||
private int length;
|
||||
|
||||
/**
|
||||
* The register count for this variable
|
||||
*/
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* The variable type
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* The variable's unit
|
||||
*/
|
||||
private @Nullable String unit;
|
||||
|
||||
/**
|
||||
* The minimal value (or null if not applicable)
|
||||
*/
|
||||
private @Nullable Double minVal;
|
||||
|
||||
/**
|
||||
* The maximum value (or null if not applicable)
|
||||
*/
|
||||
private @Nullable Double maxVal;
|
||||
|
||||
/**
|
||||
* Constructor to set the member variables
|
||||
*
|
||||
* @param variable The variable's number
|
||||
* @param name The variable's name
|
||||
* @param group The variable's group
|
||||
* @param access Access possibilities
|
||||
* @param length Number of expected characters when writing to / reading from Modbus
|
||||
* @param count Exact number of characters to write to Modbus
|
||||
* @param type Variable type (string, integer or float)
|
||||
* @param unit Variable's unit
|
||||
* @param minVal Minimum value (only applicable for numeric values)
|
||||
* @param maxVal Maximum value (only applicable for numeric values)
|
||||
*/
|
||||
public HeliosVariable(int variable, String name, @Nullable String group, String access, int length, int count,
|
||||
String type, @Nullable String unit, @Nullable Double minVal, @Nullable Double maxVal) {
|
||||
this.variable = variable;
|
||||
this.name = name;
|
||||
this.group = group;
|
||||
this.access = access;
|
||||
this.length = length;
|
||||
this.count = count;
|
||||
this.type = type;
|
||||
this.unit = unit;
|
||||
this.minVal = minVal;
|
||||
this.maxVal = maxVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to set the member variables
|
||||
*
|
||||
* @param variable The variable's number
|
||||
* @param name The variable's name
|
||||
* @param group The variable's group
|
||||
* @param access Access possibilities
|
||||
* @param length Number of expected characters when writing to / reading from Modbus
|
||||
* @param count Exact number of characters to write to Modbus
|
||||
* @param type Variable type (string, integer or float)
|
||||
* @param unit Variable's unit
|
||||
*/
|
||||
public HeliosVariable(int variable, String name, @Nullable String group, String access, int length, int count,
|
||||
String type, String unit) {
|
||||
this(variable, name, group, access, length, count, type, unit, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to set the member variables
|
||||
*
|
||||
* @param variable The variable's number
|
||||
* @param name The variable's name
|
||||
* @param group The variable's group
|
||||
* @param access Access possibilities
|
||||
* @param length Number of expected characters when writing to / reading from Modbus
|
||||
* @param count Exact number of characters to write to Modbus
|
||||
* @param type Variable type (string, integer or float)
|
||||
*/
|
||||
public HeliosVariable(int variable, String name, @Nullable String group, String access, int length, int count,
|
||||
String type) {
|
||||
this(variable, name, group, access, length, count, type, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for variable
|
||||
*
|
||||
* @return variable
|
||||
*/
|
||||
public int getVariable() {
|
||||
return this.variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted string representation for the variable
|
||||
*
|
||||
* @return String The string representation for the variable (e.g. 'v00020' for variable number 20)
|
||||
*/
|
||||
public String getVariableString() {
|
||||
return String.format("v%05d", variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for name
|
||||
*
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for name
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for group
|
||||
*
|
||||
* @return group
|
||||
*/
|
||||
public @Nullable String getGroup() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for access
|
||||
*
|
||||
* @return access
|
||||
*/
|
||||
public String getAccess() {
|
||||
return this.access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for length
|
||||
*
|
||||
* @return length
|
||||
*/
|
||||
public int getLength() {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for count
|
||||
*
|
||||
* @return count
|
||||
*/
|
||||
public int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the type
|
||||
*/
|
||||
public String getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the unit
|
||||
*/
|
||||
public @Nullable String getUnit() {
|
||||
return this.unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for minimum value
|
||||
*
|
||||
* @return minimum value
|
||||
*/
|
||||
public @Nullable Double getMinVal() {
|
||||
return this.minVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for maximum value
|
||||
*
|
||||
* @return maximum value
|
||||
*/
|
||||
public @Nullable Double getMaxVal() {
|
||||
return this.maxVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the variable's name and prefixes the group, separated by a # if available
|
||||
*
|
||||
* @return the variable's name and prefixes the group, separated by a # if available
|
||||
*/
|
||||
public String getGroupAndName() {
|
||||
return this.group != null ? this.group + "#" + this.name : this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the variable's data are consistent
|
||||
*
|
||||
* @return true if the variable contains consistent data
|
||||
*/
|
||||
public boolean isOk() {
|
||||
boolean check;
|
||||
|
||||
// this.access has one of the allowed values
|
||||
check = (this.access.equals(HeliosVariable.ACCESS_R)) || (this.access.equals(HeliosVariable.ACCESS_W))
|
||||
|| (this.access.equals(HeliosVariable.ACCESS_RW));
|
||||
|
||||
// this.type has one of the allowed values
|
||||
check = check && ((this.type.equals(HeliosVariable.TYPE_STRING))
|
||||
|| (this.type.equals(HeliosVariable.TYPE_INTEGER)) || (this.type.equals(HeliosVariable.TYPE_FLOAT)));
|
||||
|
||||
// this.minValue and this.maxValue are either not set or minValue is less than maxValue
|
||||
Double minVal = this.getMinVal();
|
||||
Double maxVal = this.getMaxVal();
|
||||
check = check && (((minVal == null) && (maxVal == null))
|
||||
|| ((minVal != null) && (maxVal != null) && (minVal <= maxVal)));
|
||||
|
||||
// length is set
|
||||
check = check && (this.length > 0);
|
||||
|
||||
// count is set
|
||||
check = check && (this.count > 0);
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the variable has write access
|
||||
*
|
||||
* @return true if the variable has write access
|
||||
*/
|
||||
public boolean hasWriteAccess() {
|
||||
return (this.access.equals(HeliosVariable.ACCESS_W)) || (this.access.equals(HeliosVariable.ACCESS_RW));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the variable has read access
|
||||
*
|
||||
* @return true if the variable has read access
|
||||
*/
|
||||
public boolean hasReadAccess() {
|
||||
return (this.access.equals(HeliosVariable.ACCESS_R)) || (this.access.equals(HeliosVariable.ACCESS_RW));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the provided value is within the accepted range
|
||||
*
|
||||
* @param value The value as a string
|
||||
* @return true if the value is within the accepted range
|
||||
*/
|
||||
public boolean isInAllowedRange(String value) {
|
||||
Double minVal = this.getMinVal();
|
||||
Double maxVal = this.getMaxVal();
|
||||
if ((minVal != null) && (maxVal != null)) { // min and max value are set
|
||||
try {
|
||||
if (this.type.equals(HeliosVariable.TYPE_INTEGER)) {
|
||||
// using long becuase some variable are specified with a max of 2^32-1
|
||||
// parsing double to allow floating point values to be processed as well
|
||||
long l = new Double(value).longValue();
|
||||
return (minVal.longValue() <= l) && (maxVal.longValue() >= l);
|
||||
} else if (this.type.equals(HeliosVariable.TYPE_FLOAT)) {
|
||||
double d = Double.parseDouble(value);
|
||||
return (minVal <= d) && (maxVal >= d);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true; // no range to check
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on the type of variable this method formats the provided value according to the interpretation of its
|
||||
* value
|
||||
*
|
||||
* @param value The value to format
|
||||
* @return The formatted value
|
||||
* @throws HeliosException if the provided value doesn't fit to the variable
|
||||
*/
|
||||
public String formatPropertyValue(String value) throws HeliosException {
|
||||
switch (this.getName()) {
|
||||
case HeliosEasyControlsBindingConstants.DATE_FORMAT:
|
||||
switch (value) {
|
||||
case "0":
|
||||
return "dd.mm.yyyy";
|
||||
case "1":
|
||||
return "mm.dd.yyyy";
|
||||
case "2":
|
||||
return "yyyy.mm.dd";
|
||||
}
|
||||
throw new HeliosException(this.createErrorMessage(value));
|
||||
case HeliosEasyControlsBindingConstants.UNIT_CONFIG:
|
||||
return value.equals("1") ? "DIBt" : "PHI";
|
||||
case HeliosEasyControlsBindingConstants.KWL_BE:
|
||||
case HeliosEasyControlsBindingConstants.KWL_BEC:
|
||||
return value.equals("1") ? "On" : "Off";
|
||||
case HeliosEasyControlsBindingConstants.EXTERNAL_CONTACT:
|
||||
case HeliosEasyControlsBindingConstants.FUNCTION_TYPE_KWL_EM:
|
||||
return "Function " + value;
|
||||
case HeliosEasyControlsBindingConstants.HEAT_EXCHANGER_TYPE:
|
||||
switch (value) {
|
||||
case "0":
|
||||
return "Plastic";
|
||||
case "1":
|
||||
return "Aluminium";
|
||||
case "2":
|
||||
return "Enthalpy";
|
||||
}
|
||||
throw new HeliosException(this.createErrorMessage(value));
|
||||
case HeliosEasyControlsBindingConstants.OFFSET_EXTRACT_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_1_EXTRACT_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_2_EXTRACT_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_3_EXTRACT_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_4_EXTRACT_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_1_SUPPLY_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_2_SUPPLY_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_3_SUPPLY_AIR:
|
||||
case HeliosEasyControlsBindingConstants.VOLTAGE_FAN_STAGE_4_SUPPLY_AIR:
|
||||
return this.getUnit() != null ? value + this.getUnit() : value;
|
||||
case HeliosEasyControlsBindingConstants.ASSIGNMENT_FAN_STAGES:
|
||||
return value.equals("0") ? "0...10V" : "stepped";
|
||||
case HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_0TO2V:
|
||||
case HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_2TO4V:
|
||||
case HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_4TO6V:
|
||||
case HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_6TO8V:
|
||||
case HeliosEasyControlsBindingConstants.FAN_STAGE_STEPPED_8TO10V:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_1:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_2:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_3:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_4:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_5:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_6:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_7:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_NAME_HUMIDITY_AND_TEMP_8:
|
||||
return value;
|
||||
case HeliosEasyControlsBindingConstants.VHZ_TYPE:
|
||||
switch (value) {
|
||||
case "1":
|
||||
return "EH-basis";
|
||||
case "2":
|
||||
return "EH-EWR";
|
||||
case "3":
|
||||
return "SEWT";
|
||||
case "4":
|
||||
return "LEWT";
|
||||
}
|
||||
throw new HeliosException(this.createErrorMessage(value));
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_0:
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_1:
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_2:
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_3:
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_4:
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_5:
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_6:
|
||||
case HeliosEasyControlsBindingConstants.KWL_FTF_CONFIG_7:
|
||||
switch (value) {
|
||||
case "1":
|
||||
return "Relative Humidity";
|
||||
case "2":
|
||||
return "Temperature";
|
||||
case "3":
|
||||
return "Combined";
|
||||
}
|
||||
throw new HeliosException(this.createErrorMessage(value));
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_1:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_2:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_3:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_4:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_5:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_6:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_7:
|
||||
case HeliosEasyControlsBindingConstants.SENSOR_CONFIG_KWL_FTF_8:
|
||||
return value.equals("0") ? "No sensor" : "Sensor installed";
|
||||
case HeliosEasyControlsBindingConstants.HUMIDITY_CONTROL_STATUS:
|
||||
case HeliosEasyControlsBindingConstants.CO2_CONTROL_STATUS:
|
||||
case HeliosEasyControlsBindingConstants.VOC_CONTROL_STATUS:
|
||||
switch (value) {
|
||||
case "0":
|
||||
return "Off";
|
||||
case "1":
|
||||
return "Stepped";
|
||||
case "2":
|
||||
return "Continuous";
|
||||
}
|
||||
throw new HeliosException(this.createErrorMessage(value));
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private String createErrorMessage(String value) {
|
||||
return "Illegal value for variable " + this.getName() + ": " + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(HeliosVariable v) {
|
||||
return getVariable() - v.getVariable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getVariableString() + ": " + this.getName() + " (" + this.getAccess() + ", " + this.getType()
|
||||
+ (this.getMinVal() != null ? "[" + this.getMinVal() + "," + this.getMaxVal() + "]" : ")");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="modbus" 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>HeliosEasyControls Binding</name>
|
||||
<description>This is the binding for a Helios ventilation system with easyControls using a Modbus TCP implementation.</description>
|
||||
<author>Bernhard Bauer</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,658 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="modbus"
|
||||
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="helios-easycontrols">
|
||||
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="tcp"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Helios Ventilation</label>
|
||||
<description>Supports controlling a Helios Heat-Recovery Ventilation Device with easyControls using the Modbus Gateway
|
||||
TCP</description>
|
||||
<category>HVAC</category>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="general" typeId="general"/>
|
||||
<channel-group id="operation" typeId="operation"/>
|
||||
<channel-group id="unitConfig" typeId="unitConfig"/>
|
||||
<channel-group id="profiles" typeId="profiles"/>
|
||||
<channel-group id="humidityControl" typeId="humidityControl"/>
|
||||
<channel-group id="co2Control" typeId="co2Control"/>
|
||||
<channel-group id="vocControl" typeId="vocControl"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="refreshInterval" type="integer" unit="ms" min="30000">
|
||||
<label>Refresh Interval</label>
|
||||
<description>Refresh interval</description>
|
||||
<default>60000</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
<!-- Channel Group Types -->
|
||||
|
||||
<channel-group-type id="general">
|
||||
<label>General</label>
|
||||
<description>General Parameters / Status Information</description>
|
||||
<channels>
|
||||
<!-- General Status Infos -->
|
||||
<channel id="preHeaterStatus" typeId="onOff">
|
||||
<label>Pre-Heater Status</label>
|
||||
<description>Pre-Heater Status</description>
|
||||
</channel>
|
||||
<channel id="bypassStatus" typeId="bypassStatus"/>
|
||||
<!-- Temperatures -->
|
||||
<channel id="nhzDuctSensor" typeId="temperature">
|
||||
<label>After Heater Duct Temperature</label>
|
||||
</channel>
|
||||
<channel id="nhzReturnSensor" typeId="temperature">
|
||||
<label>After Heater Return Temperature</label>
|
||||
</channel>
|
||||
<channel id="vhzDuctSensor" typeId="temperature">
|
||||
<label>Pre-Heater Duct Temperature</label>
|
||||
</channel>
|
||||
<channel id="temperatureOutsideAir" typeId="temperature">
|
||||
<label>Outside Air Temperature</label>
|
||||
</channel>
|
||||
<channel id="temperatureSupplyAir" typeId="temperature">
|
||||
<label>Supply Air Temperature</label>
|
||||
</channel>
|
||||
<channel id="temperatureOutgoingAir" typeId="temperature">
|
||||
<label>Outgoing Air Temperature</label>
|
||||
</channel>
|
||||
<channel id="temperatureExtractAir" typeId="temperature">
|
||||
<label>Extract Air Temperature</label>
|
||||
</channel>
|
||||
<!-- RPM -->
|
||||
<channel id="supplyAirRpm" typeId="rpm">
|
||||
<label>Supply Air Fan RPM</label>
|
||||
</channel>
|
||||
<channel id="extractAirRpm" typeId="rpm">
|
||||
<label>Extract Air Fan RPM</label>
|
||||
</channel>
|
||||
<!-- Filter Change -->
|
||||
<channel id="filterChangeRemainingTime" typeId="filterChangeRemainingTime"/>
|
||||
<!-- Operating Hours -->
|
||||
<channel id="operatingHoursSupplyAirVent" typeId="operatingHours">
|
||||
<label>Operating Hours Supply Air Fan</label>
|
||||
</channel>
|
||||
<channel id="operatingHoursExtractAirVent" typeId="operatingHours">
|
||||
<label>Operating Hours Extract Air Fan</label>
|
||||
</channel>
|
||||
<channel id="operatingHoursVhz" typeId="operatingHours">
|
||||
<label>Operating Hours Pre-Heater</label>
|
||||
</channel>
|
||||
<channel id="operatingHoursNhz" typeId="operatingHours">
|
||||
<label>Operating Hours After Heater</label>
|
||||
</channel>
|
||||
<!-- Power -->
|
||||
<channel id="outputPowerVhz" typeId="outputPower">
|
||||
<label>Output Power Pre-Heater</label>
|
||||
</channel>
|
||||
<channel id="outputPowerNhz" typeId="outputPower">
|
||||
<label>Output Power After Heater</label>
|
||||
</channel>
|
||||
<!-- Infos / Warnings / Errors -->
|
||||
<channel id="errors" typeId="errors"/>
|
||||
<channel id="warnings" typeId="warnings"/>
|
||||
<channel id="infos" typeId="infos"/>
|
||||
<channel id="noOfErrors" typeId="noOfErrors"/>
|
||||
<channel id="noOfWarnings" typeId="noOfWarnings"/>
|
||||
<channel id="noOfInfos" typeId="noOfInfos"/>
|
||||
<channel id="errorsMsg" typeId="message"/>
|
||||
<channel id="warningsMsg" typeId="message"/>
|
||||
<channel id="infosMsg" typeId="message"/>
|
||||
<channel id="statusFlags" typeId="message"/>
|
||||
<!-- System Settings -->
|
||||
<channel id="sysdate" typeId="sysdate"/>
|
||||
<channel id="summerWinter" typeId="summerWinter"/>
|
||||
<!-- Software / Firmware -->
|
||||
<channel id="autoSwUpdate" typeId="enableDisable">
|
||||
<label>Automatic SW Updates</label>
|
||||
<description>Indicates if automatic software updates are enabled</description>
|
||||
</channel>
|
||||
<channel id="accessHeliosPortal" typeId="enableDisable">
|
||||
<label>Access Helios Portal</label>
|
||||
<description>Indicates if access to Helios portal is enabled</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="operation">
|
||||
<label>Operation</label>
|
||||
<description>Control of operating mode</description>
|
||||
<channels>
|
||||
<!-- Party Mode -->
|
||||
<channel id="partyModeDuration" typeId="duration">
|
||||
<label>Party Mode Duration</label>
|
||||
<description>Party mode duration (in minutes)</description>
|
||||
</channel>
|
||||
<channel id="partyModeFanStage" typeId="fanStage">
|
||||
<label>Party Mode Fan Stage</label>
|
||||
<description>Party mode fan stage</description>
|
||||
</channel>
|
||||
<channel id="partyModeRemainingTime" typeId="remainingTime">
|
||||
<label>Party Mode Remaining Time</label>
|
||||
<description>Party mode remaining time</description>
|
||||
</channel>
|
||||
<channel id="partyModeStatus" typeId="onOff">
|
||||
<label>Party Mode Status</label>
|
||||
<description>Party mode status</description>
|
||||
</channel>
|
||||
<!-- Standby Mode -->
|
||||
<channel id="standbyModeDuration" typeId="duration">
|
||||
<label>Standby Mode Duration</label>
|
||||
<description>Standby mode duration (in minutes)</description>
|
||||
</channel>
|
||||
<channel id="standbyModeFanStage" typeId="fanStage">
|
||||
<label>Standby Mode Fan Stage</label>
|
||||
<description>Standby mode fan stage</description>
|
||||
</channel>
|
||||
<channel id="standbyModeRemainingTime" typeId="remainingTime">
|
||||
<label>Standby Mode Remaining Time</label>
|
||||
<description>Standby mode remaining time</description>
|
||||
</channel>
|
||||
<channel id="standbyModeStatus" typeId="onOff">
|
||||
<label>Standby Mode Status</label>
|
||||
<description>Standby mode status</description>
|
||||
</channel>
|
||||
<!-- Holiday Programme -->
|
||||
<channel id="holidayProgramme" typeId="holidayProgramme"/>
|
||||
<channel id="holidayProgrammeFanStage" typeId="fanStage"/>
|
||||
<channel id="holidayProgrammeStart" typeId="date">
|
||||
<label>Holiday Programme Start</label>
|
||||
<description>Holiday programme start</description>
|
||||
</channel>
|
||||
<channel id="holidayProgrammeEnd" typeId="date">
|
||||
<label>Holiday Programme End</label>
|
||||
<description>Holiday programme end</description>
|
||||
</channel>
|
||||
<channel id="holidayProgrammeInterval" typeId="holidayProgrammeInterval"/>
|
||||
<channel id="holidayProgrammeActivationTime" typeId="holidayProgrammeActivationTime"/>
|
||||
<!-- Operating Mode / Fan Stage -->
|
||||
<channel id="operatingMode" typeId="operatingMode"/>
|
||||
<channel id="fanStage" typeId="fanStage"/>
|
||||
<channel id="percentageFanStage" typeId="percentage">
|
||||
<label>Percentage Fan Stage</label>
|
||||
<description>Fan stage in percent</description>
|
||||
</channel>
|
||||
<channel id="extractAirFanStage" typeId="fanStage"/>
|
||||
<channel id="supplyAirFanStage" typeId="fanStage"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="unitConfig">
|
||||
<label>Unit Config</label>
|
||||
<description>Configuration parameters of the ventilation unit</description>
|
||||
<channels>
|
||||
<!-- Fan Stage Configuration -->
|
||||
<channel id="minFanStage" typeId="minFanStage"/>
|
||||
<!-- Bypass Configuration -->
|
||||
<channel id="bypassRoomTemperature" typeId="bypassRoomTemperature"/>
|
||||
<channel id="bypassMinOutsideTemperature" typeId="bypassMinOutsideTemperature"/>
|
||||
<channel id="bypassFrom" typeId="bypass"/>
|
||||
<channel id="bypassTo" typeId="bypass"/>
|
||||
<!-- Comfort Temperature -->
|
||||
<channel id="comfortTemp" typeId="comfortTemp"/>
|
||||
<!-- Error Output Function -->
|
||||
<channel id="errorOutputFunction" typeId="errorOutputFunction"/>
|
||||
<!-- Filter Change -->
|
||||
<channel id="filterChange" typeId="filterChange"/>
|
||||
<channel id="filterChangeInterval" typeId="filterChangeInterval"/>
|
||||
<!-- System Components and Extensions -->
|
||||
<channel id="runOnTimeVhzNhz" typeId="runOnTimeVhzNhz"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="profiles">
|
||||
<label>Profiles</label>
|
||||
<description>Profiles for Device Operation</description>
|
||||
<channels>
|
||||
<channel id="weekProfileNhz" typeId="weekProfileNhz"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="humidityControl">
|
||||
<label>Humidity Control</label>
|
||||
<description>Config of Sensors for Humidity and/or Temperature Control</description>
|
||||
<channels>
|
||||
<channel id="humidityControlSetValue" typeId="humidityControlSetValue"/>
|
||||
<channel id="humidityControlSteps" typeId="humidityControlSteps"/>
|
||||
<channel id="humidityStopTime" typeId="humidityStopTime"/>
|
||||
<!-- External Humidity Sensors -->
|
||||
<channel id="externalSensorKwlFtfHumidity1" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlFtfHumidity2" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlFtfHumidity3" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlFtfHumidity4" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlFtfHumidity5" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlFtfHumidity6" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlFtfHumidity7" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlFtfHumidity8" typeId="sensorValue"/>
|
||||
<!-- External Temperature Sensors -->
|
||||
<channel id="externalSensorKwlFtfTemperature1" typeId="temperature"/>
|
||||
<channel id="externalSensorKwlFtfTemperature2" typeId="temperature"/>
|
||||
<channel id="externalSensorKwlFtfTemperature3" typeId="temperature"/>
|
||||
<channel id="externalSensorKwlFtfTemperature4" typeId="temperature"/>
|
||||
<channel id="externalSensorKwlFtfTemperature5" typeId="temperature"/>
|
||||
<channel id="externalSensorKwlFtfTemperature6" typeId="temperature"/>
|
||||
<channel id="externalSensorKwlFtfTemperature7" typeId="temperature"/>
|
||||
<channel id="externalSensorKwlFtfTemperature8" typeId="temperature"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="co2Control">
|
||||
<label>CO2 Control</label>
|
||||
<description>Config of Sensors for CO2 Control</description>
|
||||
<channels>
|
||||
<channel id="co2ControlSetValue" typeId="ppmControlSetValue">
|
||||
<label>CO2 Control Status</label>
|
||||
<description>CO2 control status</description>
|
||||
</channel>
|
||||
<channel id="co2ControlSteps" typeId="ppmControlSteps">
|
||||
<label>CO2 Control Steps</label>
|
||||
<description>CO2 control steps (in ppm)</description>
|
||||
</channel>
|
||||
<!-- External CO2 Sensors -->
|
||||
<channel id="externalSensorKwlCo21" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlCo22" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlCo23" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlCo24" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlCo25" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlCo26" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlCo27" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlCo28" typeId="sensorValue"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="vocControl">
|
||||
<label>VOC Control</label>
|
||||
<description>Config of Sensors for VOC Control</description>
|
||||
<channels>
|
||||
<channel id="vocControlSetValue" typeId="ppmControlSetValue">
|
||||
<label>VOC Control Status</label>
|
||||
<description>VOC control status</description>
|
||||
</channel>
|
||||
<channel id="vocControlSteps" typeId="ppmControlSteps">
|
||||
<label>CO2 Control Steps</label>
|
||||
<description>CO2 control steps (in ppm)</description>
|
||||
</channel>
|
||||
<!-- External CO2 Sensors -->
|
||||
<channel id="externalSensorKwlVoc1" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlVoc2" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlVoc3" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlVoc4" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlVoc5" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlVoc6" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlVoc7" typeId="sensorValue"/>
|
||||
<channel id="externalSensorKwlVoc8" typeId="sensorValue"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
|
||||
<!-- Channel Types -->
|
||||
|
||||
<channel-type id="sysdate" advanced="true">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>System Date and Time</label>
|
||||
<description>The KWL's system date and time</description>
|
||||
<category>Time</category>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="summerWinter" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Summertime / Wintertime</label>
|
||||
<description>Indicates if summertime or wintertime is active</description>
|
||||
<category>Time</category>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Wintertime</option>
|
||||
<option value="1">Summertime</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="enableDisable">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Enable/Disable</label>
|
||||
<description>Used for functionality that can be enabled or disabled</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="minFanStage" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Minimum Fan Stage</label>
|
||||
<description>Minimum fan stage (0 or 1)</description>
|
||||
<category>HVAC</category>
|
||||
<state min="0" max="1" step="1" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="onOff">
|
||||
<item-type>Switch</item-type>
|
||||
<label>On/Off</label>
|
||||
<description>Used for configurations that can be on or off</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="humidityControlSetValue" advanced="true">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Humidity Control Set Value</label>
|
||||
<description>Humidity control set value (in percent)</description>
|
||||
<category>Humidity</category>
|
||||
<state min="20" max="80" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="humidityControlSteps" advanced="true">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Humidity Control Steps</label>
|
||||
<description>Humidity control steps (in percent)</description>
|
||||
<category>Humidity</category>
|
||||
<state min="5" max="20" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="humidityStopTime" advanced="true">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Humidity Stop Time</label>
|
||||
<description>Humidity stop time in hours (0-24)</description>
|
||||
<category>Humidity</category>
|
||||
<state min="0" max="24" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="ppmControlSetValue" advanced="true">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Control Set Value</label>
|
||||
<description>Control set value (in ppm)</description>
|
||||
<category>Gas</category>
|
||||
<state min="300" max="2000" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="ppmControlSteps" advanced="true">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Control Steps</label>
|
||||
<description>Control steps (in ppm)</description>
|
||||
<category>Gas</category>
|
||||
<state min="50" max="400" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="comfortTemp" advanced="true">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Comfort Temperature</label>
|
||||
<description>Comfort temperature</description>
|
||||
<category>Temperature</category>
|
||||
<state min="10" max="25" step="0.1" pattern="%.1f %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="duration" advanced="false">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Duration</label>
|
||||
<description>Duration for operating mode (in minutes)</description>
|
||||
<state min="5" max="180" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="fanStage" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Fan Stage</label>
|
||||
<description>Fan stage</description>
|
||||
<category>HVAC</category>
|
||||
<state min="0" max="4" step="1" pattern="%d" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="remainingTime" advanced="false">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Remaining Time</label>
|
||||
<description>Remaining time for operating mode (in minutes)</description>
|
||||
<state min="0" max="180" step="1" pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="operatingMode" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Operating Mode</label>
|
||||
<description>Operating mode (automatic/manual)</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Automatic</option>
|
||||
<option value="1">Manual</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="percentage" advanced="false">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Percentage</label>
|
||||
<description>Percentage</description>
|
||||
<state min="0" max="100" step="1" pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="temperature" advanced="false">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>Temperature in °C</description>
|
||||
<category>Temperature</category>
|
||||
<state min="-27" max="9998.9" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorValue" advanced="false">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Sensor Value</label>
|
||||
<description>Measurement of a sensor</description>
|
||||
<state min="0" max="9998.9" step="0.1" pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="weekProfileNhz" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Week Profile Afterheater</label>
|
||||
<description>Week profile afterheater</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Standard 1</option>
|
||||
<option value="1">Standard 2</option>
|
||||
<option value="2">Fixed value</option>
|
||||
<option value="3">Individual 1</option>
|
||||
<option value="4">Individual 2</option>
|
||||
<option value="5">NA</option>
|
||||
<option value="6">Off</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="rpm" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>RPM</label>
|
||||
<description>RPM</description>
|
||||
<state min="0" max="9999" step="1" pattern="%d rpm" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="holidayProgramme" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Holiday Programme</label>
|
||||
<description>Holiday programme</description>
|
||||
<category>Vacation</category>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Off</option>
|
||||
<option value="1">Interval</option>
|
||||
<option value="2">Constant</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="date" advanced="false">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Date</label>
|
||||
<description>Date</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="holidayProgrammeInterval" advanced="true">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Holiday Programme Interval</label>
|
||||
<description>Holiday programme interval in hours</description>
|
||||
<category>Vacation</category>
|
||||
<state min="1" max="24" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="holidayProgrammeActivationTime" advanced="true">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Holiday Programme Activation Time</label>
|
||||
<description>Holiday programme activation time in minutes</description>
|
||||
<category>Vacation</category>
|
||||
<state min="5" max="300" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="runOnTimeVhzNhz" advanced="true">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Stopping Time Preheater/Afterheater</label>
|
||||
<description>Stopping time preheater/afterheater in seconds</description>
|
||||
<category>Heating</category>
|
||||
<state min="60" max="120" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="errorOutputFunction" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Error Output Function</label>
|
||||
<description>Error output function (collective error or just error)</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="1">Collective error</option>
|
||||
<option value="2">Only error</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="filterChange" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Filter Change</label>
|
||||
<description>Filter change</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">No</option>
|
||||
<option value="1">Yes</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="filterChangeInterval" advanced="true">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Filter Change Interval</label>
|
||||
<description>Filter change interval in months</description>
|
||||
<state min="1" max="12" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="filterChangeRemainingTime" advanced="true">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Filter Change Remaining Time</label>
|
||||
<description>Filter change remaining time in minutes</description>
|
||||
<state min="1" max="550000" step="1" pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="bypassRoomTemperature" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Bypass Room Temperature</label>
|
||||
<description>Bypass room temperature</description>
|
||||
<category>Temperature</category>
|
||||
<state min="10" max="40" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="bypassMinOutsideTemperature" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Bypass Minimum Outside Temperature</label>
|
||||
<description>Bypass minimum outside temperature</description>
|
||||
<category>Temperature</category>
|
||||
<state min="5" max="20" step="1" pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="offsetExtractAir" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Offset Extract Air</label>
|
||||
<description>Offset extract air</description>
|
||||
<category>HVAC</category>
|
||||
<state pattern="%.1f" readOnly="false"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="operatingHours" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Operating Hours</label>
|
||||
<description>Operating hours (in minutes)</description>
|
||||
<category>Time</category>
|
||||
<state min="0" max="100000000" step="1" pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="outputPower" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Output Power</label>
|
||||
<description>Output power of preheater/afterheater (in percent)</description>
|
||||
<category>Energy</category>
|
||||
<state min="0" max="100000000" step="1" pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="errors" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Errors</label>
|
||||
<description>Errors as integer value</description>
|
||||
<state min="0" max="4294967295" step="1" pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="warnings" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Warnings</label>
|
||||
<description>Warnings as integer value</description>
|
||||
<state min="0" max="255" step="1" pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="infos" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Infos</label>
|
||||
<description>Infos as integer value</description>
|
||||
<state min="0" max="255" step="1" pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="noOfErrors" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Number of Errors</label>
|
||||
<description>Number of bit-coded errors</description>
|
||||
<state min="0" max="32" step="1" pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="noOfWarnings" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Number of Warnings</label>
|
||||
<description>Number of bit-coded warnings</description>
|
||||
<state min="0" max="8" step="1" pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="noOfInfos" advanced="false">
|
||||
<item-type>Number</item-type>
|
||||
<label>Number of Infos</label>
|
||||
<description>Number of bit-coded infos</description>
|
||||
<state min="0" max="8" step="1" pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="message" advanced="false">
|
||||
<item-type>String</item-type>
|
||||
<label>Errors / Warnings / Infos</label>
|
||||
<description>Errors / warnings / infos as string</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="sensorConfig" advanced="false">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Sensor Configuration</label>
|
||||
<description>Sensor configuration (installed or not)</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="bypassStatus" advanced="true">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Bypass Status</label>
|
||||
<description>Status of the bypass</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="bypass" advanced="true">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Bypass Active from/to (Day and Month)</label>
|
||||
<description>Bypass will be active/deactivated from that day and month on</description>
|
||||
<category>Time</category>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"articleDescription": {"group": "general", "variable": 0, "access": "RW", "length": 31, "count": 20, "type": "string"},
|
||||
"refNo": {"group": "general", "variable": 1, "access": "RW", "length": 16, "count": 12, "type": "string"},
|
||||
"macAddress": {"group": "general", "variable": 2, "access": "R", "length": 18, "count": 13, "type": "string"},
|
||||
"language": {"group": "general", "variable": 3, "access": "RW", "length": 2, "count": 5, "type": "string"},
|
||||
"date": {"group": "general", "variable": 4, "access": "RW", "length": 10, "count": 9, "type": "string"},
|
||||
"time": {"group": "general", "variable": 5, "access": "RW", "length": 10, "count": 9, "type": "string"},
|
||||
"summerWinter": {"group": "general", "variable": 6, "access": "RW", "length": 1, "count": 5, "type": "int"},
|
||||
"autoSwUpdate": {"group": "general", "variable": 7, "access": "RW", "length": 1, "count": 5, "type": "int"},
|
||||
"accessHeliosPortal": {"group": "general", "variable": 8, "access": "RW", "length": 1, "count": 5, "type": "int"},
|
||||
"voltageFanStage1ExtractAir": {"group": "unitConfig", "variable": 12, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"voltageFanStage2ExtractAir": {"group": "unitConfig", "variable": 13, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"voltageFanStage3ExtractAir": {"group": "unitConfig", "variable": 14, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"voltageFanStage4ExtractAir": {"group": "unitConfig", "variable": 15, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"voltageFanStage1SupplyAir": {"group": "unitConfig", "variable": 16, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"voltageFanStage2SupplyAir": {"group": "unitConfig", "variable": 17, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"voltageFanStage3SupplyAir": {"group": "unitConfig", "variable": 18, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"voltageFanStage4SupplyAir": {"group": "unitConfig", "variable": 19, "access": "RW", "length": 3, "count": 6, "type": "float", "unit": "V", "minVal": 1.6, "maxVal": 10.0},
|
||||
"minFanStage": {"group": "unitConfig", "variable": 20, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"kwlBe": {"group": "unitConfig", "variable": 21, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"kwlBec": {"group": "unitConfig", "variable": 22, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"unitConfig": {"group": "unitConfig", "variable": 23, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"preHeaterStatus": {"group": "general", "variable": 24, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"kwlFtfConfig0": {"group": "humidityControl", "variable": 25, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"kwlFtfConfig1": {"group": "humidityControl", "variable": 26, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"kwlFtfConfig2": {"group": "humidityControl", "variable": 27, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"kwlFtfConfig3": {"group": "humidityControl", "variable": 28, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"kwlFtfConfig4": {"group": "humidityControl", "variable": 29, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"kwlFtfConfig5": {"group": "humidityControl", "variable": 30, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"kwlFtfConfig6": {"group": "humidityControl", "variable": 31, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"kwlFtfConfig7": {"group": "humidityControl", "variable": 32, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"humidityControlStatus": {"group": "humidityControl", "variable": 33, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 2},
|
||||
"humidityControlSetValue": {"group": "humidityControl", "variable": 34, "access": "RW", "length": 2, "count": 5, "type": "int", "unit": "%", "minVal": 20, "maxVal": 80},
|
||||
"humidityControlSteps": {"group": "humidityControl", "variable": 35, "access": "RW", "length": 2, "count": 5, "type": "int", "unit": "%", "minVal": 5, "maxVal": 20},
|
||||
"humidityStopTime": {"group": "humidityControl", "variable": 36, "access": "RW", "length": 2, "count": 5, "type": "int", "unit": "h", "minVal": 0, "maxVal": 24},
|
||||
"co2ControlStatus": {"group": "co2Control", "variable": 37, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 2},
|
||||
"co2ControlSetValue": {"group": "co2Control", "variable": 38, "access": "RW", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 300, "maxVal": 2000},
|
||||
"co2ControlSteps": {"group": "co2Control", "variable": 39, "access": "RW", "length": 3, "count": 6, "type": "int", "unit": "ppm", "minVal": 50, "maxVal": 400},
|
||||
"vocControlStatus": {"group": "vocControl", "variable": 40, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 2},
|
||||
"vocControlSetValue": {"group": "vocControl", "variable": 41, "access": "RW", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 300, "maxVal": 2000},
|
||||
"vocControlSteps": {"group": "vocControl", "variable": 42, "access": "RW", "length": 3, "count": 6, "type": "int", "unit": "ppm", "minVal": 50, "maxVal": 400},
|
||||
"comfortTemp": {"group": "unitConfig", "variable": 43, "access": "RW", "length": 4, "count": 6, "type": "int", "unit": "°C", "minVal": 10, "maxVal": 25},
|
||||
"timeZoneDifferenceToGmt": {"group": "general", "variable": 51, "access": "RW", "length": 3, "count": 6, "type": "int", "unit": "h", "minVal": -12, "maxVal": 14},
|
||||
"dateFormat": {"group": "general", "variable": 52, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 2},
|
||||
"heatExchangerType": {"group": "unitConfig", "variable": 53, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 3},
|
||||
"partyModeDuration": {"group": "operation", "variable": 91, "access": "RW", "length": 3, "count": 6, "type": "int", "unit": "min", "minVal": 5, "maxVal": 180},
|
||||
"partyModeFanStage": {"group": "operation", "variable": 92, "access": "RW", "length": 3, "count": 5, "type": "int", "minVal": 0, "maxVal": 4},
|
||||
"partyModeRemainingTime": {"group": "operation", "variable": 93, "access": "R", "length": 3, "count": 6, "type": "int", "unit": "min", "minVal": 0, "maxVal": 180},
|
||||
"partyModeStatus": {"group": "operation", "variable": 94, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"standbyModeDuration": {"group": "operation", "variable": 96, "access": "RW", "length": 3, "count": 6, "type": "int", "unit": "min", "minVal": 5, "maxVal": 180},
|
||||
"standbyModeFanStage": {"group": "operation", "variable": 97, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 4},
|
||||
"standbyModeRemainingTime": {"group": "operation", "variable": 98, "access": "R", "length": 3, "count": 6, "type": "int", "unit": "min", "minVal": 0, "maxVal": 180},
|
||||
"standbyModeStatus": {"group": "operation", "variable": 99, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"operatingMode": {"group": "operation", "variable": 101, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"fanStage": {"group": "operation", "variable": 102, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 4},
|
||||
"percentageFanStage": {"group": "operation", "variable": 103, "access": "R", "length": 3, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 100},
|
||||
"temperatureOutsideAir": {"group": "general", "variable": 104, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"temperatureSupplyAir": {"group": "general", "variable": 105, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"temperatureOutgoingAir": {"group": "general", "variable": 106, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"temperatureExtractAir": {"group": "general", "variable": 107, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"vhzDuctSensor": {"group": "general", "variable": 108, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"nhzReturnSensor": {"group": "general", "variable": 110, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity1": {"group": "humidityControl", "variable": 111, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity2": {"group": "humidityControl", "variable": 112, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity3": {"group": "humidityControl", "variable": 113, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity4": {"group": "humidityControl", "variable": 114, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity5": {"group": "humidityControl", "variable": 115, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity6": {"group": "humidityControl", "variable": 116, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity7": {"group": "humidityControl", "variable": 117, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfHumidity8": {"group": "humidityControl", "variable": 118, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "%", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature1": {"group": "humidityControl", "variable": 119, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature2": {"group": "humidityControl", "variable": 120, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature3": {"group": "humidityControl", "variable": 121, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature4": {"group": "humidityControl", "variable": 122, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature5": {"group": "humidityControl", "variable": 123, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature6": {"group": "humidityControl", "variable": 124, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature7": {"group": "humidityControl", "variable": 125, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlFtfTemperature8": {"group": "humidityControl", "variable": 126, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"externalSensorKwlCo21": {"group": "co2Control", "variable": 128, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlCo22": {"group": "co2Control", "variable": 129, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlCo23": {"group": "co2Control", "variable": 130, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlCo24": {"group": "co2Control", "variable": 131, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlCo25": {"group": "co2Control", "variable": 132, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlCo26": {"group": "co2Control", "variable": 133, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlCo27": {"group": "co2Control", "variable": 134, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlCo28": {"group": "co2Control", "variable": 135, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc1": {"group": "vocControl", "variable": 136, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc2": {"group": "vocControl", "variable": 137, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc3": {"group": "vocControl", "variable": 138, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc4": {"group": "vocControl", "variable": 139, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc5": {"group": "vocControl", "variable": 140, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc6": {"group": "vocControl", "variable": 141, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc7": {"group": "vocControl", "variable": 142, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"externalSensorKwlVoc8": {"group": "vocControl", "variable": 143, "access": "R", "length": 4, "count": 6, "type": "int", "unit": "ppm", "minVal": 0, "maxVal": 9998},
|
||||
"nhzDuctSensor": {"group": "general", "variable": 146, "access": "R", "length": 7, "count": 8, "type": "int", "unit": "°C", "minVal": -27, "maxVal": 9998},
|
||||
"weekProfileNhz": {"group": "profiles", "variable": 201, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 6},
|
||||
"serNo": {"group": "general", "variable": 303, "access": "RW", "length": 16, "count": 12, "type": "string"},
|
||||
"prodCode": {"group": "general", "variable": 304, "access": "RW", "length": 13, "count": 11, "type": "string"},
|
||||
"supplyAirRpm": {"group": "general", "variable": 348, "access": "R", "length": 4, "count": 6, "type": "int", "minVal": 0, "maxVal": 9999},
|
||||
"extractAirRpm": {"group": "general", "variable": 349, "access": "R", "length": 4, "count": 6, "type": "int", "minVal": 0, "maxVal": 9999},
|
||||
"logout": {"group": "general", "variable": 403, "access": "W", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 1},
|
||||
"holidayProgramme": {"group": "operation", "variable": 601, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 2},
|
||||
"holidayProgrammeFanStage": {"group": "operation", "variable": 602, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 4},
|
||||
"holidayProgrammeStart": {"group": "operation", "variable": 603, "access": "RW", "length": 10, "count": 9, "type": "string"},
|
||||
"holidayProgrammeEnd": {"group": "operation", "variable": 604, "access": "RW", "length": 10, "count": 9, "type": "string"},
|
||||
"holidayProgrammeInterval": {"group": "operation", "variable": 605, "access": "RW", "length": 2, "count": 5, "type": "int", "unit": "h", "minVal": 1, "maxVal": 24},
|
||||
"holidayProgrammeActivationTime": {"group": "operation", "variable": 606, "access": "RW", "length": 3, "count": 6, "type": "int", "unit": "min", "minVal": 5, "maxVal": 300},
|
||||
"vhzType": {"group": "unitConfig", "variable": 1010, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 4},
|
||||
"functionTypeKwlEm": {"group": "unitConfig", "variable": 1017, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 2},
|
||||
"runOnTimeVhzNhz": {"group": "unitConfig", "variable": 1019, "access": "RW", "length": 3, "count": 6, "type": "int", "unit": "s", "minVal": 60, "maxVal": 120},
|
||||
"externalContact": {"group": "unitConfig", "variable": 1020, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 6},
|
||||
"errorOutputFunction": {"group": "unitConfig", "variable": 1021, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 2},
|
||||
"filterChange": {"group": "unitConfig", "variable": 1031, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"filterChangeInterval": {"group": "unitConfig", "variable": 1032, "access": "RW", "length": 2, "count": 5, "type": "int", "minVal": 0, "maxVal": 12},
|
||||
"filterChangeRemainingTime": {"group": "general", "variable": 1033, "access": "R", "length": 10, "count": 9, "type": "int", "unit": "min", "minVal": 2, "maxVal": 4294967295},
|
||||
"filterChangeReset": {"group": "general", "variable": 1034, "access": "W", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"bypassRoomTemperature": {"group": "unitConfig", "variable": 1035, "access": "RW", "length": 2, "count": 5, "type": "int", "unit": "°C", "minVal": 10, "maxVal": 40},
|
||||
"bypassMinOutsideTemperature": {"group": "unitConfig", "variable": 1036, "access": "RW", "length": 2, "count": 5, "type": "int", "unit": "°C", "minVal": 5, "maxVal": 20},
|
||||
"tbd": {"group": "general", "variable": 1037, "access": "RW", "length": 2, "count": 5, "type": "int", "unit": "°C", "minVal": 3, "maxVal": 10},
|
||||
"factorySettingWzu": {"group": "general", "variable": 1041, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 1},
|
||||
"factoryReset": {"group": "general", "variable": 1042, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 1},
|
||||
"supplyAirFanStage": {"group": "operation", "variable": 1050, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 4},
|
||||
"extractAirFanStage": {"group": "operation", "variable": 1051, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 4},
|
||||
"fanStageStepped0to2v": {"group": "unitConfig", "variable": 1061, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 2},
|
||||
"fanStageStepped2to4v": {"group": "unitConfig", "variable": 1062, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 4},
|
||||
"fanStageStepped4to6v": {"group": "unitConfig", "variable": 1063, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 4},
|
||||
"fanStageStepped6to8v": {"group": "unitConfig", "variable": 1064, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 4},
|
||||
"fanStageStepped8to10v": {"group": "unitConfig", "variable": 1065, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 4},
|
||||
"offsetExtractAir": {"group": "unitConfig", "variable": 1066, "access": "RW", "length": 10, "count": 9, "type": "float"},
|
||||
"assignmentFanStages": {"group": "unitConfig", "variable": 1068, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorNameHumidityAndTemp1": {"group": "humidityControl", "variable": 1071, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameHumidityAndTemp2": {"group": "humidityControl", "variable": 1072, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameHumidityAndTemp3": {"group": "humidityControl", "variable": 1073, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameHumidityAndTemp4": {"group": "humidityControl", "variable": 1074, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameHumidityAndTemp5": {"group": "humidityControl", "variable": 1075, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameHumidityAndTemp6": {"group": "humidityControl", "variable": 1076, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameHumidityAndTemp7": {"group": "humidityControl", "variable": 1077, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameHumidityAndTemp8": {"group": "humidityControl", "variable": 1078, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo21": {"group": "co2Control", "variable": 1081, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo22": {"group": "co2Control", "variable": 1082, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo23": {"group": "co2Control", "variable": 1083, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo24": {"group": "co2Control", "variable": 1084, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo25": {"group": "co2Control", "variable": 1085, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo26": {"group": "co2Control", "variable": 1086, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo27": {"group": "co2Control", "variable": 1087, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameCo28": {"group": "co2Control", "variable": 1088, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc1": {"group": "vocControl", "variable": 1091, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc2": {"group": "vocControl", "variable": 1092, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc3": {"group": "vocControl", "variable": 1093, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc4": {"group": "vocControl", "variable": 1094, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc5": {"group": "vocControl", "variable": 1095, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc6": {"group": "vocControl", "variable": 1096, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc7": {"group": "vocControl", "variable": 1097, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"sensorNameVoc8": {"group": "vocControl", "variable": 1098, "access": "RW", "length": 15, "count": 12, "type": "string"},
|
||||
"softwareVersionBasis": {"group": "general", "variable": 1101, "access": "R", "length": 5, "count": 7, "type": "float", "minVal": 0.0, "maxVal": 99.99},
|
||||
"operatingHoursSupplyAirVent": {"group": "general", "variable": 1103, "access": "R", "length": 10, "count": 9, "type": "int", "unit": "min", "minVal": 0, "maxVal": 4294967295},
|
||||
"operatingHoursExtractAirVent": {"group": "general", "variable": 1104, "access": "R", "length": 10, "count": 9, "type": "int", "unit": "min", "minVal": 0, "maxVal": 4294967295},
|
||||
"operatingHoursVhz": {"group": "general", "variable": 1105, "access": "R", "length": 10, "count": 9, "type": "int", "unit": "min", "minVal": 0, "maxVal": 4294967295},
|
||||
"operatingHoursNhz": {"group": "general", "variable": 1106, "access": "R", "length": 10, "count": 9, "type": "int", "unit": "min", "minVal": 0, "maxVal": 4294967295},
|
||||
"outputPowerVhz": {"group": "general", "variable": 1108, "access": "R", "length": 10, "count": 9, "type": "int", "unit": "%", "minVal": 0, "maxVal": 4294967295},
|
||||
"outputPowerNhz": {"group": "general", "variable": 1109, "access": "R", "length": 10, "count": 9, "type": "int", "unit": "%", "minVal": 0, "maxVal": 4294967295},
|
||||
"resetFlag": {"group": "general", "variable": 1120, "access": "W", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 1},
|
||||
"errors": {"group": "general", "variable": 1123, "access": "R", "length": 10, "count": 9, "type": "int", "minVal": 0, "maxVal": 4294967295},
|
||||
"warnings": {"group": "general", "variable": 1124, "access": "R", "length": 3, "count": 6, "type": "int", "minVal": 0, "maxVal": 255},
|
||||
"infos": {"group": "general", "variable": 1125, "access": "R", "length": 3, "count": 6, "type": "int", "minVal": 0, "maxVal": 255},
|
||||
"noOfErrors": {"group": "general", "variable": 1300, "access": "R", "length": 2, "count": 5, "type": "int", "minVal": 0, "maxVal": 32},
|
||||
"noOfWarnings": {"group": "general", "variable": 1301, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 8},
|
||||
"noOfInfos": {"group": "general", "variable": 1302, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 8},
|
||||
"errorsMsg": {"group": "general", "variable": 1303, "access": "R", "length": 32, "count": 20, "type": "string"},
|
||||
"warningsMsg": {"group": "general", "variable": 1304, "access": "R", "length": 8, "count": 8, "type": "string"},
|
||||
"infosMsg": {"group": "general", "variable": 1305, "access": "R", "length": 8, "count": 8, "type": "string"},
|
||||
"statusFlags": {"group": "general", "variable": 1306, "access": "R", "length": 32, "count": 20, "type": "string"},
|
||||
"globalManualWebUpdate": {"group": "general", "variable": 2013, "access": "RW", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 1},
|
||||
"portalGlobalsErrorForWeb": {"group": "general", "variable": 2014, "access": "R", "length": 3, "count": 6, "type": "int", "minVal": 1, "maxVal": 255},
|
||||
"clearError": {"group": "general", "variable": 2015, "access": "W", "length": 1, "count": 5, "type": "int", "minVal": 1, "maxVal": 1},
|
||||
"sensorConfigKwlFtf1": {"group": "humidityControl", "variable": 2020, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorConfigKwlFtf2": {"group": "humidityControl", "variable": 2021, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorConfigKwlFtf3": {"group": "humidityControl", "variable": 2022, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorConfigKwlFtf4": {"group": "humidityControl", "variable": 2023, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorConfigKwlFtf5": {"group": "humidityControl", "variable": 2024, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorConfigKwlFtf6": {"group": "humidityControl", "variable": 2025, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorConfigKwlFtf7": {"group": "humidityControl", "variable": 2026, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"sensorConfigKwlFtf8": {"group": "humidityControl", "variable": 2027, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"bypassStatus": {"group": "general", "variable": 2119, "access": "R", "length": 1, "count": 5, "type": "int", "minVal": 0, "maxVal": 1},
|
||||
"bypassFromDay": {"group": "unitConfig", "variable": 2120, "access": "RW", "length": 2, "count": 5, "type": "int", "minVal": 1, "maxVal": 31},
|
||||
"bypassFromMonth": {"group": "unitConfig", "variable": 2121, "access": "RW", "length": 2, "count": 5, "type": "int", "minVal": 1, "maxVal": 12},
|
||||
"bypassToDay": {"group": "unitConfig", "variable": 2128, "access": "RW", "length": 2, "count": 5, "type": "int", "minVal": 1, "maxVal": 31},
|
||||
"bypassToMonth": {"group": "unitConfig", "variable": 2129, "access": "RW", "length": 2, "count": 5, "type": "int", "minVal": 1, "maxVal": 12}
|
||||
}
|
||||
Reference in New Issue
Block a user