[touchwand] - Add support for Risco alarm system sensors and AcWand thermostat (#10748)

* notify listeners on status change using discovery 

Signed-off-by: Roie Geron <roie.geron@gmail.com>
This commit is contained in:
Roie Geron 2021-05-30 12:46:41 +03:00 committed by GitHub
parent f99f4b6361
commit 6ae7f98134
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 772 additions and 30 deletions

View File

@ -9,6 +9,11 @@ TouchWand products are compatible with most major Z-Wave products, IP controlled
## Supported Things
This binding supports switches, shutters dimmers alarm sensors and wall controllers configured in Touchwand Wanderfull™ Hub Controller.
The binding also supports [AcWand™](http://www.touchwand.com/products/touchwand-acwand/) - smart control for your air conditioner controller.
![AcWand](http://www.touchwand.com/wp-content/uploads/2019/04/AcWand-300x350.png)
## Control and Status
@ -17,10 +22,13 @@ This binding supports switches, shutters dimmers alarm sensors and wall controll
3. **dimmer** - control - ON/OFF/BRIGHTNESS
4. **wallcontroller** - control - LONG/SHORT
5. **alarmsensor** - status channels depend on alarm sensor type
5. **bsensor** - binary status channels depend on alarm sensor type (motion, door , smoke)
6. **thermostat** - AcWand™ smart control for your air conditioner
## Discovery
After adding TouchWand Hub the auto discovery will add all switches dimmers alarm sensors and shutters to the inbox.
After adding TouchWand Hub the auto discovery will add all suppored devuces to inbox.
Auto discovery scans priodically and add to the Inbox new devices added to the Touchwand Wanderfull™ Hub
## Bridge Configuration
@ -32,7 +40,6 @@ After adding TouchWand Hub the auto discovery will add all switches dimmers alar
| password | Touchwand hub password | string | yes |
| ipAddress | Touchwand hub hostname or IP address | string | yes |
| port | Management port (default 80) | integer | no |
| statusrefresh | Unit status refresh interval in seconds | integer | no |
| addSecondaryUnits | If the controller is primary, add secondary controllers units as well | bool | no |
@ -46,23 +53,37 @@ No thing configuration is needed
note **Touchwand Wanderfull™** supports various types of alarm sensors such as water leak, door/window sensor and motion sensor.
Alarm Sensor thing represents a generic sensor, relevant sensor channels will be displayed once a sensor is added as a Thing.
## Switch Shutters Channels
| Channel Type ID | Item Type | Description
|-------------------|--------------------|-----------------------------------------------------------------------|
| switch | Switch | This channel supports switching the device on and off. |
| shutter | Rollershutter | This channel controls the shutter position |
| brightness | Dimmer | This channel supports adjusting the brightness value. |
| wallaction | String | This channel indicate SHORT or LONG wallcontroller button pressed |
## Alarm Sensors Channels
| Channel Type ID | Item Type | Description
|-------------------|--------------------|-----------------------------------------------------------------------|
| illumination | Number:Illuminance | This channel shows the current illuminance measured by the sensor. |
| temperature | Number:Temperature | This channel shows the current temperature measured by the sensor. |
| leak | Switch | This channel alert when water leak is detected by the sensor |
| motion | Switch | This channel alert when motion detected by the sensor. |
| smoke | Switch | This channel alert when smoke detected by the sensor. |
| isOpen | Contact | This channel shows the status of Door/Window sensor. |
| battery_level | Number | This channel shows the battery level. |
| battery_low | Switch | This channel indicates whether the battery is low or not. |
| wallaction | String | This channel indicate SHORT or LONG wallcontroller button pressed |
## Thermostat Channels
| Channel Type ID | Item Type | Description
|-------------------|--------------------|-----------------------------------------------------------------------|
| State | Switch | Set and read the device state ON or OFF. |
| targetTemperature | Number:Temperature | Shows the current set point of the thrermostat. |
| roomTemperature | Number:Temperature | Shows the current termprature measured by the thermostat. |
| mode | String | Set/Read Thermostat mode - Cool, Heat, Fan, Dry, Auto |
| fanLevel | String | Set/Read fan leval - Low, Medium, High, Auto |
## Full Example
@ -98,7 +119,7 @@ Rollershutter Rollershutter_346 "Living Room South shutter" {channel="
```
/* Switches and Dimmers */
Switch Switch_408 "Strairs light" {channel="touchwand:switch:1921681116:408:switch"}
Switch Switch_408 "Stairs light" {channel="touchwand:switch:1921681116:408:switch"}
Switch Switch_411 "South Garden light" {channel="touchwand:switch:1921681116:411:switch"}
Dimmer Switch_415 "Living Room Ceiling dimmer" {channel="touchwand:switch:1921681116:415:switch"}
Switch Switch_418 "South Garden light" {channel="touchwand:switch:1921681116:418:switch"}

View File

@ -144,8 +144,7 @@ public class TouchWandAlarmSensorHandler extends TouchWandBaseUnitHandler {
toBeRemovedChannels.remove(thing.getChannel(CHANNEL_DOORWINDOW));
break;
case SENSOR_TYPE_LEAK:
Channel channel = thing.getChannel(CHANNEL_LEAK);
toBeRemovedChannels.remove(channel);
toBeRemovedChannels.remove(thing.getChannel(CHANNEL_LEAK));
break;
}
}

View File

@ -0,0 +1,136 @@
/**
* Copyright (c) 2010-2021 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.touchwand.internal;
import static org.openhab.binding.touchwand.internal.TouchWandBindingConstants.*;
import java.util.ArrayList;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.touchwand.internal.dto.TouchWandBSensorUnitData;
import org.openhab.binding.touchwand.internal.dto.TouchWandUnitData;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.binding.builder.ThingBuilder;
import org.openhab.core.types.Command;
/**
* The {@link TouchWandBSensorHandler} is responsible for handling command for Binary Sensor unit
*
* @author Roie Geron - Initial contribution
*/
@NonNullByDefault
public class TouchWandBSensorHandler extends TouchWandBaseUnitHandler {
private boolean isFirstUpdateTouchWandUnitState = true;
public TouchWandBSensorHandler(Thing thing) {
super(thing);
}
@Override
void updateTouchWandUnitState(TouchWandUnitData unitData) {
if (unitData instanceof TouchWandBSensorUnitData) {
if (isFirstUpdateTouchWandUnitState) {
removeUnsupportedChannels((TouchWandBSensorUnitData) unitData);
isFirstUpdateTouchWandUnitState = false;
}
String sensorSubType = ((TouchWandBSensorUnitData) unitData).getIdData().getSubType();
switch (sensorSubType) {
case BSENSOR_SUBTYPE_DOORWINDOW:
updateChannelDoorWindow((TouchWandBSensorUnitData) unitData);
break;
case BSENSOR_SUBTYPE_MOTION:
updateChannelMotion((TouchWandBSensorUnitData) unitData);
break;
case BSENSOR_SUBTYPE_SMOKE:
updateChannelSmoke((TouchWandBSensorUnitData) unitData);
break;
default:
}
} else {
logger.warn("updateTouchWandUnitState incompatible TouchWandUnitData instance");
}
}
@Override
void touchWandUnitHandleCommand(Command command) {
}
void updateChannelDoorWindow(TouchWandBSensorUnitData unitData) {
OpenClosedType myOpenClose;
String isOpen = unitData.getCurrStatus();
logger.debug("recieved status {} from door unit {} ", isOpen, unitData.getName());
if (isOpen.equals(BSENSOR_STATUS_OPEN)) {
myOpenClose = OpenClosedType.OPEN;
} else if (isOpen.equals(BSENSOR_STATUS_CLOSE)) {
myOpenClose = OpenClosedType.CLOSED;
} else {
logger.debug("TouchWandBSensorUnitData illegal update value {}", isOpen);
return;
}
updateState(CHANNEL_DOORWINDOW, myOpenClose);
}
void updateChannelMotion(TouchWandBSensorUnitData unitData) {
String motion = unitData.getCurrStatus();
logger.debug("recieved status {} from motion unit {} ", motion, unitData.getName());
OnOffType status;
if (motion.equals(BSENSOR_STATUS_OPEN)) {
status = OnOffType.ON;
} else if (motion.equals(BSENSOR_STATUS_CLOSE)) {
status = OnOffType.OFF;
} else {
logger.debug("TouchWandBSensorUnitData illegal update value {}", motion);
return;
}
updateState(CHANNEL_MOTION, status);
}
void updateChannelSmoke(TouchWandBSensorUnitData unitData) {
String hasSmoke = unitData.getCurrStatus();
OnOffType status;
if (hasSmoke.equals(BSENSOR_STATUS_OPEN)) {
status = OnOffType.ON;
} else if (hasSmoke.equals(BSENSOR_STATUS_CLOSE)) {
status = OnOffType.OFF;
} else {
logger.debug("TouchWandBSensorUnitData illegal update value {}", hasSmoke);
return;
}
updateState(CHANNEL_SMOKE, status);
}
void removeUnsupportedChannels(TouchWandBSensorUnitData unitData) {
ArrayList<Channel> toBeRemovedChannels = new ArrayList<>(thing.getChannels());
String sensorSubType = unitData.getIdData().getSubType();
switch (sensorSubType) {
case BSENSOR_SUBTYPE_DOORWINDOW:
toBeRemovedChannels.remove(thing.getChannel(CHANNEL_DOORWINDOW));
break;
case BSENSOR_SUBTYPE_MOTION:
toBeRemovedChannels.remove(thing.getChannel(CHANNEL_MOTION));
break;
case BSENSOR_SUBTYPE_SMOKE:
Channel channel = thing.getChannel(CHANNEL_SMOKE);
toBeRemovedChannels.remove(channel);
break;
}
ThingBuilder thingBuilder = editThing();
thingBuilder.withoutChannels(toBeRemovedChannels);
updateThing(thingBuilder.build());
}
}

View File

@ -47,7 +47,8 @@ public abstract class TouchWandBaseUnitHandler extends BaseThingHandler implemen
private static final int UNITS_STATUS_UPDATE_DELAY_SEC = 1;
protected final Logger logger = LoggerFactory.getLogger(TouchWandBaseUnitHandler.class);
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_SHUTTER, THING_TYPE_SWITCH,
THING_TYPE_WALLCONTROLLER, THING_TYPE_DIMMER, THING_TYPE_ALARMSENSOR);
THING_TYPE_WALLCONTROLLER, THING_TYPE_DIMMER, THING_TYPE_ALARMSENSOR, THING_TYPE_BSENSOR,
THING_TYPE_THERMOSTAT);
protected String unitId = "";
protected @Nullable TouchWandBridgeHandler bridgeHandler;

View File

@ -37,6 +37,8 @@ public class TouchWandBindingConstants {
public static final ThingTypeUID THING_TYPE_WALLCONTROLLER = new ThingTypeUID(BINDING_ID, "wallcontroller");
public static final ThingTypeUID THING_TYPE_DIMMER = new ThingTypeUID(BINDING_ID, "dimmer");
public static final ThingTypeUID THING_TYPE_ALARMSENSOR = new ThingTypeUID(BINDING_ID, "alarmsensor");
public static final ThingTypeUID THING_TYPE_BSENSOR = new ThingTypeUID(BINDING_ID, "bsensor");
public static final ThingTypeUID THING_TYPE_THERMOSTAT = new ThingTypeUID(BINDING_ID, "thermostat");
// List of all Channel ids
public static final String CHANNEL_SWITCH = "switch";
@ -51,6 +53,12 @@ public class TouchWandBindingConstants {
public static final String CHANNEL_ILLUMINATION = "illumination";
public static final String CHANNEL_DOORWINDOW = "isOpen";
public static final String CHANNEL_TEMPERATURE = "temperature";
public static final String CHANNEL_THERMOSTAT_STATE = "state";
public static final String CHANNEL_THERMOSTAT_TARGET_TEMPERATURE = "targetTemperature";
public static final String CHANNEL_THERMOSTAT_ROOM_TEMPERATURE = "roomTemperature";
public static final String CHANNEL_THERMOSTAT_MODE = "mode";
public static final String CHANNEL_THERMOSTAT_FAN_LEVEL = "fanLevel";
public static final String CHANNEL_SMOKE = "smoke";
// List of configuration parameters
@ -70,11 +78,18 @@ public class TouchWandBindingConstants {
public static final String CONNECTIVITY_KNX = "knx";
public static final String CONNECTIVITY_ZWAVE = "zwave";
public static final String CONNECTIVITY_RISCO = "risco";
public static final String CONNECTIVITY_PIMA = "pima";
public static final String CONNECTIVITY_ACWAND = "acwand";
// commands
public static final String SWITCH_STATUS_ON = "255";
public static final String SWITCH_STATUS_OFF = "0";
// thermostat commands
public static final String THERMOSTAT_STATE_ON = "1";
public static final String THERMOSTAT_STATE_OFF = "0";
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<>();
static {
@ -83,6 +98,8 @@ public class TouchWandBindingConstants {
SUPPORTED_THING_TYPES_UIDS.add(THING_TYPE_WALLCONTROLLER);
SUPPORTED_THING_TYPES_UIDS.add(THING_TYPE_DIMMER);
SUPPORTED_THING_TYPES_UIDS.add(THING_TYPE_ALARMSENSOR);
SUPPORTED_THING_TYPES_UIDS.add(THING_TYPE_BSENSOR);
SUPPORTED_THING_TYPES_UIDS.add(THING_TYPE_THERMOSTAT);
}
public static final String TYPE_WALLCONTROLLER = "WallController";
@ -90,6 +107,8 @@ public class TouchWandBindingConstants {
public static final String TYPE_SHUTTER = "shutter";
public static final String TYPE_DIMMER = "dimmer";
public static final String TYPE_ALARMSENSOR = "AlarmSensor";
public static final String TYPE_BSENSOR = "bsensor";
public static final String TYPE_THERMOSTAT = "thermostat";
public static final String TYPE_UNKNOWN = "unknown";
public static final int SENSOR_TYPE_TEMPERATURE = 1;
@ -98,6 +117,15 @@ public class TouchWandBindingConstants {
public static final int SENSOR_TYPE_DOOR_WINDOW = 10;
public static final int SENSOR_TYPE_MOTION = 12;
// bsensor currStatus options
public static final String BSENSOR_STATUS_OPEN = "open";
public static final String BSENSOR_STATUS_CLOSE = "close";
public static final String BSENSOR_SUBTYPE_DOORWINDOW = "doors &windows";
public static final String BSENSOR_SUBTYPE_MOTION = "motion";
public static final String BSENSOR_SUBTYPE_SMOKE = "smoke";
public static final String[] SUPPORTED_TOUCHWAND_TYPES = { TYPE_WALLCONTROLLER, TYPE_SWITCH, TYPE_SHUTTER,
TYPE_DIMMER, TYPE_ALARMSENSOR };
TYPE_DIMMER, TYPE_ALARMSENSOR, TYPE_BSENSOR, TYPE_THERMOSTAT };
}

View File

@ -47,7 +47,6 @@ import org.slf4j.LoggerFactory;
public class TouchWandBridgeHandler extends BaseBridgeHandler implements TouchWandUnitStatusUpdateListener {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_BRIDGE);
private final Logger logger = LoggerFactory.getLogger(TouchWandBridgeHandler.class);
private int statusRefreshRateSec;
private boolean addSecondaryUnits;
private @Nullable TouchWandWebSockets touchWandWebSockets;
private Map<String, TouchWandUnitUpdateListener> unitUpdateListeners = new ConcurrentHashMap<>();
@ -73,7 +72,6 @@ public class TouchWandBridgeHandler extends BaseBridgeHandler implements TouchWa
host = config.ipAddress;
port = config.port;
statusRefreshRateSec = config.statusrefresh;
addSecondaryUnits = config.addSecondaryUnits;
isRunning = true;
@ -108,10 +106,6 @@ public class TouchWandBridgeHandler extends BaseBridgeHandler implements TouchWa
return addSecondaryUnits;
}
public int getStatusRefreshTime() {
return statusRefreshRateSec;
}
@Override
public synchronized void dispose() {
isRunning = false;

View File

@ -70,6 +70,10 @@ public class TouchWandHandlerFactory extends BaseThingHandlerFactory {
return new TouchWandDimmerHandler(thing);
} else if (THING_TYPE_ALARMSENSOR.equals(thingTypeUID)) {
return new TouchWandAlarmSensorHandler(thing);
} else if (THING_TYPE_BSENSOR.equals(thingTypeUID)) {
return new TouchWandBSensorHandler(thing);
} else if (THING_TYPE_THERMOSTAT.equals(thingTypeUID)) {
return new TouchWandThermostatHandler(thing);
}
return null;

View File

@ -67,6 +67,11 @@ public class TouchWandRestClient {
private static final String ACTION_SHUTTER_STOP = "{\"id\":%s,\"value\":0,\"type\":\"stop\"}";
private static final String ACTION_SHUTTER_POSITION = "{\"id\":%s,\"value\":%s}";
private static final String ACTION_DIMMER_POSITION = "{\"id\":%s,\"value\":%s}";
private static final String ACTION_THERMOSTAT_ON = "{\"id\":%s,\"value\":" + THERMOSTAT_STATE_ON + "}";
private static final String ACTION_THERMOSTAT_OFF = "{\"id\":%s,\"value\":" + THERMOSTAT_STATE_OFF + "}";
private static final String ACTION_THERMOSTAT_MODE = "{\"id\":%s,\"ac-all\":\"mode\",\"fan\":\"%s\"}";
private static final String ACTION_THERMOSTAT_FAN_LEVEL = "{\"id\":%s,\"ac-all\":\"fan\",\"fan\":\"%s\"}";
private static final String ACTION_THERMOSTAT_TARGET_TEMPERATURE = "{\"id\":%s,\"ac-all\":\"temp\",\"temp_val\":%s}";
private static final String CONTENT_TYPE_APPLICATION_JSON = MimeTypes.Type.APPLICATION_JSON.asString();
@ -170,6 +175,32 @@ public class TouchWandRestClient {
cmdUnitAction(action);
}
public void cmdThermostatOnOff(String id, OnOffType onoff) {
String action;
if (OnOffType.OFF.equals(onoff)) {
action = String.format(ACTION_THERMOSTAT_OFF, id);
} else {
action = String.format(ACTION_THERMOSTAT_ON, id);
}
cmdUnitAction(action);
}
public void cmdThermostatMode(String id, String mode) {
String action = String.format(ACTION_THERMOSTAT_MODE, id, mode);
cmdUnitAction(action);
}
public void cmdThermostatFanLevel(String id, String fanLevel) {
String action = String.format(ACTION_THERMOSTAT_FAN_LEVEL, id, fanLevel);
cmdUnitAction(action);
}
public void cmdThermostatTargetTemperature(String id, String targetTemperature) {
String action = String.format(ACTION_THERMOSTAT_TARGET_TEMPERATURE, id, targetTemperature);
cmdUnitAction(action);
}
private String cmdUnitAction(String action) {
String response = "";
if (isConnected) {

View File

@ -0,0 +1,115 @@
/**
* Copyright (c) 2010-2021 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.touchwand.internal;
import static org.openhab.binding.touchwand.internal.TouchWandBindingConstants.*;
import javax.measure.quantity.Temperature;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.touchwand.internal.dto.TouchWandThermostatUnitData;
import org.openhab.binding.touchwand.internal.dto.TouchWandUnitData;
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.thing.Thing;
import org.openhab.core.types.Command;
/**
* The {@link TouchWandAlarmSensorHandler} is responsible for handling command for Alarm Sensor unit
*
* @author Roie Geron - Initial contribution
*/
@NonNullByDefault
public class TouchWandThermostatHandler extends TouchWandBaseUnitHandler {
public TouchWandThermostatHandler(Thing thing) {
super(thing);
}
@Override
void updateTouchWandUnitState(TouchWandUnitData unitData) {
if (unitData instanceof TouchWandThermostatUnitData) {
TouchWandThermostatUnitData thermostat = (TouchWandThermostatUnitData) unitData;
updateThermostatState(thermostat);
updateTargetTemperature(thermostat);
updateRoomTemperature(thermostat);
updateMode(thermostat);
updateFanLevel(thermostat);
} else {
logger.warn("updateTouchWandUnitState incompatible TouchWandUnitData instance");
}
}
@Override
void touchWandUnitHandleCommand(Command command) {
TouchWandBridgeHandler touchWandBridgeHandler = bridgeHandler;
if (touchWandBridgeHandler != null) {
if (command instanceof OnOffType) {
touchWandBridgeHandler.touchWandClient.cmdThermostatOnOff(unitId, (OnOffType) command);
} else {
String sCommand = command.toString();
switch (sCommand) {
case "cool":
case "heat":
case "fan":
case "auto":
case "dry":
touchWandBridgeHandler.touchWandClient.cmdThermostatMode(unitId, sCommand);
break;
case "low":
case "medium":
case "high":
touchWandBridgeHandler.touchWandClient.cmdThermostatFanLevel(unitId, sCommand);
break;
case "fanAuto":
touchWandBridgeHandler.touchWandClient.cmdThermostatFanLevel(unitId, "auto");
break;
default:
touchWandBridgeHandler.touchWandClient.cmdThermostatTargetTemperature(unitId, sCommand);
break;
}
}
}
}
void updateThermostatState(TouchWandThermostatUnitData unitData) {
String state = unitData.getCurrStatus().getState();
updateState(CHANNEL_THERMOSTAT_STATE, OnOffType.from(state));
}
void updateTargetTemperature(TouchWandThermostatUnitData unitData) {
int targetTemperature = unitData.getCurrStatus().getTargetTemperature();
QuantityType<Temperature> temperatureValue = new QuantityType<Temperature>(targetTemperature, SIUnits.CELSIUS);
updateState(CHANNEL_THERMOSTAT_TARGET_TEMPERATURE, temperatureValue);
}
void updateRoomTemperature(TouchWandThermostatUnitData unitData) {
int roomTemperature = unitData.getCurrStatus().getRoomTemperature();
QuantityType<Temperature> temperatureValue = new QuantityType<Temperature>(roomTemperature, SIUnits.CELSIUS);
updateState(CHANNEL_THERMOSTAT_ROOM_TEMPERATURE, temperatureValue);
}
void updateMode(TouchWandThermostatUnitData unitData) {
String mode = unitData.getCurrStatus().getMode();
StringType newVal = StringType.valueOf(mode);
updateState(CHANNEL_THERMOSTAT_MODE, newVal);
}
void updateFanLevel(TouchWandThermostatUnitData unitData) {
String fanLevel = unitData.getCurrStatus().getFanLevel();
StringType newVal = StringType.valueOf(fanLevel);
updateState(CHANNEL_THERMOSTAT_FAN_LEVEL, newVal);
}
}

View File

@ -26,6 +26,5 @@ public class TouchwandBridgeConfiguration {
public String password = "";
public String ipAddress = "";
public int port;
public int statusrefresh;
public boolean addSecondaryUnits;
}

View File

@ -31,7 +31,6 @@ import org.openhab.binding.touchwand.internal.dto.TouchWandUnitData;
import org.openhab.binding.touchwand.internal.dto.TouchWandUnitFromJson;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
@ -51,13 +50,13 @@ import com.google.gson.JsonSyntaxException;
* @author Roie Geron - Initial contribution
*/
@NonNullByDefault
public class TouchWandUnitDiscoveryService extends AbstractDiscoveryService
implements DiscoveryService, ThingHandlerService {
public class TouchWandUnitDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
private static final int SEARCH_TIME_SEC = 10;
private static final int SCAN_INTERVAL_SEC = 60;
private static final int LINK_DISCOVERY_SERVICE_INITIAL_DELAY_SEC = 5;
private static final String[] CONNECTIVITY_OPTIONS = { CONNECTIVITY_KNX, CONNECTIVITY_ZWAVE };
private static final String[] CONNECTIVITY_OPTIONS = { CONNECTIVITY_KNX, CONNECTIVITY_ZWAVE, CONNECTIVITY_RISCO,
CONNECTIVITY_PIMA, CONNECTIVITY_ACWAND };
private @NonNullByDefault({}) TouchWandBridgeHandler touchWandBridgeHandler;
private final Logger logger = LoggerFactory.getLogger(TouchWandUnitDiscoveryService.class);
@ -115,6 +114,12 @@ public class TouchWandUnitDiscoveryService extends AbstractDiscoveryService
case TYPE_ALARMSENSOR:
addDeviceDiscoveryResult(touchWandUnit, THING_TYPE_ALARMSENSOR);
break;
case TYPE_BSENSOR:
addDeviceDiscoveryResult(touchWandUnit, THING_TYPE_BSENSOR);
break;
case TYPE_THERMOSTAT:
addDeviceDiscoveryResult(touchWandUnit, THING_TYPE_THERMOSTAT);
break;
default:
continue;
}
@ -125,7 +130,7 @@ public class TouchWandUnitDiscoveryService extends AbstractDiscoveryService
}
}
} catch (JsonSyntaxException msg) {
logger.warn("Could not parse list units response {}", msg.getMessage());
logger.warn("Could not parse list units response error:{} ", msg.getMessage());
}
}

View File

@ -0,0 +1,109 @@
/**
* Copyright (c) 2010-2021 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.touchwand.internal.dto;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link IdData} implements IdData data class.
*
* @author Roie Geron - Initial contribution
*/
@NonNullByDefault
public class IdData {
private String status = "";
private String subType = "";
private String zone = "";
private String id = "";
private boolean hasOff;
private boolean hasMode;
private String type = "";
private boolean isTempSensor;
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public boolean isHasOff() {
return this.hasOff;
}
public boolean getHasOff() {
return this.hasOff;
}
public void setHasOff(boolean hasOff) {
this.hasOff = hasOff;
}
public boolean isHasMode() {
return this.hasMode;
}
public boolean getHasMode() {
return this.hasMode;
}
public void setHasMode(boolean hasMode) {
this.hasMode = hasMode;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public boolean isIsTempSensor() {
return this.isTempSensor;
}
public boolean getIsTempSensor() {
return this.isTempSensor;
}
public void setIsTempSensor(boolean isTempSensor) {
this.isTempSensor = isTempSensor;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSubType() {
return subType;
}
public void setSubType(String subType) {
this.subType = subType;
}
public String getZone() {
return zone;
}
public void setZone(String zone) {
this.zone = zone;
}
}

View File

@ -0,0 +1,46 @@
/**
* Copyright (c) 2010-2021 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.touchwand.internal.dto;
/**
* The {@link TouchWandBSensorUnitData} implements BSensor units property.
*
* @author Roie Geron - Initial contribution
*/
public class TouchWandBSensorUnitData extends TouchWandUnitData {
private String currStatus = "";
private IdData idData;
@Override
public String getCurrStatus() {
if (currStatus == null) {
currStatus = new String("");
}
return currStatus;
}
public void setCurrStatus(String currStatus) {
this.currStatus = currStatus;
}
public IdData getIdData() {
return idData;
}
public void setIdData(IdData idData) {
this.idData = idData;
}
}

View File

@ -0,0 +1,118 @@
/**
* Copyright (c) 2010-2021 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.touchwand.internal.dto;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link TouchWandThermostatCurrentStatus} implements Thermostat unit
* CurrentStatus data property.
*
* @author Roie Geron - Initial contribution
*/
@NonNullByDefault
public class TouchWandThermostatCurrentStatus {
private String ac_type = "";
private int value;
private int thermo_mode;
private String mode = "";
private int temp;
private int thermo_temp;
private String state = "";
private int roomTemp;
private String fan = "";
private String communication_status = "";
public String getAcType() {
return this.ac_type;
}
public void setAcType(String ac_type) {
this.ac_type = ac_type;
}
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value = value;
}
public int getThermoMode() {
return this.thermo_mode;
}
public void setThermoMode(int thermo_mode) {
this.thermo_mode = thermo_mode;
}
public String getMode() {
return this.mode;
}
public void setMode(String mode) {
this.mode = mode;
}
public int getTemp() {
return this.temp;
}
public void setTemp(int temp) {
this.temp = temp;
}
public int getTargetTemperature() {
return this.thermo_temp;
}
public void setTargetTemperature(int thermo_temp) {
this.thermo_temp = thermo_temp;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public int getRoomTemperature() {
return this.roomTemp;
}
public void setRoomTemperature(int roomTemp) {
this.roomTemp = roomTemp;
}
public String getFanLevel() {
return this.fan;
}
public void setFanLevel(String fan) {
this.fan = fan;
}
public String getCommunicationStatus() {
return this.communication_status;
}
public void setCommunicationStatus(String communication_status) {
this.communication_status = communication_status;
}
}

View File

@ -0,0 +1,33 @@
/**
* Copyright (c) 2010-2021 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.touchwand.internal.dto;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link TouchWandUnitDataAlarmSensor} implements Alarm Sensor unit
* data property.
*
* @author Roie Geron - Initial contribution
*/
@NonNullByDefault
public class TouchWandThermostatUnitData extends TouchWandUnitData {
private TouchWandThermostatCurrentStatus currStatus = new TouchWandThermostatCurrentStatus();
@Override
public TouchWandThermostatCurrentStatus getCurrStatus() {
return this.currStatus;
}
}

View File

@ -12,14 +12,11 @@
*/
package org.openhab.binding.touchwand.internal.dto;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link TouchWandUnitData} implements unit property.
*
* @author Roie Geron - Initial contribution
*/
@NonNullByDefault
public abstract class TouchWandUnitData {
private Integer id = 0;
@ -99,6 +96,9 @@ public abstract class TouchWandUnitData {
}
public String getStatus() {
if (status == null) {
status = new String("");
}
return status;
}

View File

@ -66,6 +66,12 @@ public class TouchWandUnitFromJson {
.create();
touchWandUnit = builder.fromJson(jsonUnit, TouchWandUnitDataAlarmSensor.class);
break;
case TYPE_BSENSOR:
touchWandUnit = gson.fromJson(jsonUnit, TouchWandBSensorUnitData.class);
break;
case TYPE_THERMOSTAT:
touchWandUnit = gson.fromJson(jsonUnit, TouchWandThermostatUnitData.class);
break;
case TYPE_UNKNOWN:
touchWandUnit = new TouchWandUnknownTypeUnitData();
break;

View File

@ -31,12 +31,6 @@
<default>80</default>
<advanced>true</advanced>
</parameter>
<parameter name="statusrefresh" type="integer" unit="s">
<default>120</default>
<description>Unit status refresh interval (seconds)</description>
<label>Refresh</label>
<advanced>true</advanced>
</parameter>
<parameter name="addSecondaryUnits" type="boolean">
<default>false</default>
<description>If the controller is primary, add secondary controllers units as well</description>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="touchwand"
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="bsensor">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"></bridge-type-ref>
</supported-bridge-type-refs>
<label>TouchWand Binary Sensor Unit</label>
<channels>
<channel id="isOpen" typeId="isOpen"/>
<channel id="motion" typeId="motion"/>
<channel id="smoke" typeId="smoke"/>
</channels>
</thing-type>
<channel-type id="isOpen">
<item-type>Contact</item-type>
<label>Open Status</label>
<category>Contact</category>
<state readOnly="true"></state>
</channel-type>
<channel-type id="motion">
<item-type>Switch</item-type>
<label>Motion Detected</label>
<category>Motion</category>
<state readOnly="true"></state>
</channel-type>
<channel-type id="smoke">
<item-type>Switch</item-type>
<label>Smoke Detected</label>
<category>Smoke</category>
<state readOnly="true"></state>
</channel-type>
</thing:thing-descriptions>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="touchwand"
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="thermostat">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"></bridge-type-ref>
</supported-bridge-type-refs>
<label>TouchWand Thermostat Unit</label>
<channels>
<channel id="state" typeId="state"/>
<channel id="targetTemperature" typeId="targetTemperature"/>
<channel id="roomTemperature" typeId="roomTemperature"/>
<channel id="mode" typeId="mode"/>
<channel id="fanLevel" typeId="fanLevel"/>
</channels>
</thing-type>
<channel-type id="state">
<item-type>Switch</item-type>
<label>AC On Off State</label>
</channel-type>
<channel-type id="targetTemperature">
<item-type>Number:Temperature</item-type>
<label>Target Temperature</label>
<description>The set point temperature</description>
<category>Temperature</category>
<state min="16" max="30" step="1" pattern="%.1f %unit%">
</state>
</channel-type>
<channel-type id="roomTemperature">
<item-type>Number:Temperature</item-type>
<label>Room Temperature</label>
<description>Current room temperature</description>
<category>Temperature</category>
<state pattern="%.1f %unit%" readOnly="true">
</state>
</channel-type>
<channel-type id="mode">
<item-type>String</item-type>
<label>Mode</label>
<description>Thermostat mode (Cool, Heat, Fan, Dry, Auto)</description>
<state readOnly="false">
<options>
<option value="cool">Cool</option>
<option value="heat">Heat</option>
<option value="fan">Fan</option>
<option value="auto">Auto</option>
<option value="dry">Dry</option>
</options>
</state>
</channel-type>
<channel-type id="fanLevel">
<item-type>String</item-type>
<label>Fan Level</label>
<description>Fan level (Low, Medium, High, Auto)</description>
<state readOnly="false">
<options>
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
<option value="fanAuto">Auto</option>
</options>
</state>
</channel-type>
</thing:thing-descriptions>