/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.rwesmarthome.internal.communicator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.openhab.binding.rwesmarthome.RWESmarthomeBindingProvider;
import org.openhab.binding.rwesmarthome.internal.RWESmarthomeContext;
import org.openhab.binding.rwesmarthome.internal.RWESmarthomeGenericBindingProvider.RWESmarthomeBindingConfig;
import org.openhab.binding.rwesmarthome.internal.communicator.client.RWEClient;
import org.openhab.binding.rwesmarthome.internal.communicator.client.RWEHTTPClient;
import org.openhab.binding.rwesmarthome.internal.communicator.exceptions.ConfigurationChangedException;
import org.openhab.binding.rwesmarthome.internal.communicator.exceptions.LogoutNotificationException;
import org.openhab.binding.rwesmarthome.internal.communicator.exceptions.RWESmarthomeSessionExpiredException;
import org.openhab.binding.rwesmarthome.internal.communicator.xmlresponse.GetAllLogicalDeviceStatesXMLResponse;
import org.openhab.binding.rwesmarthome.internal.communicator.xmlresponse.GetEntitiesXMLResponse;
import org.openhab.binding.rwesmarthome.internal.communicator.xmlresponse.NotificationsXMLResponse;
import org.openhab.binding.rwesmarthome.internal.model.LogicalDevice;
import org.openhab.binding.rwesmarthome.internal.model.RoomTemperatureActuator;
import org.openhab.core.library.types.IncreaseDecreaseType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.StopMoveType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The communicator to communicate with the RWE Smarthome Central.
*
* @author ollie-dev
*
*/
public class RWESmarthomeCommunicator {
private static final Logger logger = LoggerFactory.getLogger(RWESmarthomeCommunicator.class);
private RWESmarthomeSession rweSmarthomeSession;
private RWESmarthomeContext context = RWESmarthomeContext.getInstance();
private long lastEventTime = System.currentTimeMillis();
private boolean runPoller = false;
/**
* Stops the communication with the RWE Smarthome Central.
*/
public void stop() {
logger.info("Shutting down RWE Smarthome communicator");
runPoller = false;
if (rweSmarthomeSession != null) {
try {
rweSmarthomeSession.destroy();
} finally {
rweSmarthomeSession = null;
logger.info("RWE Smarthome communicator shut down.");
}
}
}
/**
* Returns the timestamp from the last RweSmarthome server event.
*/
public long getLastEventTime() {
return lastEventTime;
}
/**
* Starts the communication session with the RWE Smarthome Central.
*/
public void start() {
logger.info("Starting RWE Smarthome communicator");
try {
RWEClient client = new RWEHTTPClient();
rweSmarthomeSession = new RWESmarthomeSession(client);
context.setRweSmarthomeSession(rweSmarthomeSession);
rweSmarthomeSession.logon(context.getConfig().getUsername(), context.getConfig().getPassword(),
context.getConfig().getHost());
logger.info("Login successful.");
refreshConfiguration();
logger.info("Configuration refreshed: " + rweSmarthomeSession.getCurrentConfigurationVersion());
logFoundDevices();
runPoller = true;
subscribeForDeviceStateChanges();
logger.info("Subscribed for devicestate changes.");
subscribeForConfigurationChanges();
logger.info("Subscribed for configuration changes.");
lastEventTime = System.currentTimeMillis();
this.context.setBindingChanged(true);
} catch (Exception e) {
logger.error("Could not start RWE Smarthome communicator: " + e.getMessage(), e);
stop();
}
}
/**
* Writes the list of the found devices to the OpenHAB log.
*/
private void logFoundDevices() {
// Hashmap as helper to get a sorted exampleConfig
List<String> exampleConfig = new ArrayList<String>();
for (LogicalDevice ld : rweSmarthomeSession.getLogicalDevices().values()) {
String validParams = "";
if (LogicalDevice.Type_RoomTemperatureActuator.equals(ld.getType())) {
validParams = "settemperature, operationmodeauto";
exampleConfig.add("Number\trweSettemp" + ld.getId().substring(30) + "\t\"Solltemp "
+ ld.getLocation().getName() + " [%.1f °C]\"\t<temperature>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=settemperature\"}\n");
exampleConfig.add("Switch\trweSettempOpMode" + ld.getId().substring(30) + "\t\"Solltemp Automode "
+ ld.getLocation().getName() + "\"\t<temperature>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=operationmodeauto\"}\n");
} else if (LogicalDevice.Type_RoomTemperatureSensor.equals(ld.getType())) {
validParams = "temperature";
exampleConfig.add("Number\trweTemp" + ld.getId().substring(30) + "\t\t\"Temp "
+ ld.getLocation().getName() + " [%.1f °C]\"\t<temperature>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=temperature\"}\n");
} else if (LogicalDevice.Type_SwitchActuator.equals(ld.getType())) {
validParams = "switch";
exampleConfig.add("Switch\trweSwitch" + ld.getId().substring(30) + "\t\t\"Schalter "
+ ld.getLocation().getName() + "\"\t<switch>\t(rwe) {" + context.getBindingType() + "=\"id="
+ ld.getId() + ",param=switch\"}\n");
} else if (LogicalDevice.Type_WindowDoorSensor.equals(ld.getType())) {
validParams = "contact";
exampleConfig.add("Contact\trweContact" + ld.getId().substring(30) + "\t\"Fenster/Tür "
+ ld.getLocation().getName() + " [MAP(de.map):%s]\"\t<contact>\t(rwe) {"
+ context.getBindingType() + "=\"id=" + ld.getId() + ",param=contact\"}\n");
} else if (LogicalDevice.Type_LuminanceSensor.equals(ld.getType())) {
validParams = "luminance";
exampleConfig.add("Number\trweLuminance" + ld.getId().substring(30) + "\t\"Helligkeit "
+ ld.getLocation().getName() + " [%d %%]\"\t<slider>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=luminance\"}\n");
} else if (LogicalDevice.Type_RoomHumiditySensor.equals(ld.getType())) {
validParams = "humidity";
exampleConfig.add("Number\trweHumidity" + ld.getId().substring(30) + "\t\"Feuchtigkeit "
+ ld.getLocation().getName() + " [%.1f %%]\"\t<temperature>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=humidity\"}\n");
} else if (LogicalDevice.Type_RollerShutterActuator.equals(ld.getType())) {
validParams = "rollershutter, rollershutterinverted";
exampleConfig.add("Rollershutter\trweRollershutter" + ld.getId().substring(30) + "\t\"Rollo "
+ ld.getLocation().getName() + " [%d %%]\"\t<rollershutter>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=rollershutter\"}\n");
} else if (LogicalDevice.Type_SmokeDetectorSensor.equals(ld.getType())) {
validParams = "smokedetector";
exampleConfig.add("String\trweSmokeDetector" + ld.getId().substring(30) + "\t\"Rauchmelder "
+ ld.getLocation().getName() + " [%s]\"\t<fire>\t(rwe) {" + context.getBindingType() + "=\"id="
+ ld.getId() + ",param=smokedetector\"}\n");
} else if (LogicalDevice.Type_AlarmActuator.equals(ld.getType())) {
validParams = "alarm";
exampleConfig.add("Switch\trweAlarm" + ld.getId().substring(30) + "\t\t\"Alarm "
+ ld.getLocation().getName() + "\"\t<siren>\t(rwe) {" + context.getBindingType() + "=\"id="
+ ld.getId() + ",param=alarm\"}\n");
} else if (LogicalDevice.Type_DimmerActuator.equals(ld.getType())) {
validParams = "dimmer, dimmerinverted";
exampleConfig.add("Dimmer\trweDimmer" + ld.getId().substring(30) + "\t\"Dimmer "
+ ld.getLocation().getName() + " [%d %%]\"\t<slider>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=dimmer\"}\n");
} else if (LogicalDevice.Type_GenericActuator_Value.equals(ld.getType())) {
validParams = "variable";
exampleConfig.add("Switch\trweVariable" + ld.getId().substring(30) + "\t\"Variable " + ld.getName()
+ "\"\t<switch>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=variable\"}\n");
// RWE Power Control Solar
} else if (LogicalDevice.Type_TwoWayMeterEnergyConsumptionSensor.equals(ld.getType())) {
validParams = "totalenergy, energypermonthinkwh, energypermonthineuro, energyperdayinkwh, energyperdayineuro";
exampleConfig.add("Number\trweEnergyConsumptionTotal" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption total " + ld.getLocation().getName()
+ " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=totalenergy\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionMonthKWh" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per month " + ld.getLocation().getName()
+ " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energypermonthinkwh\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionMonthEuro" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per month " + ld.getLocation().getName()
+ " [%.2f €]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energypermonthineuro\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionDayKWh" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per day " + ld.getLocation().getName()
+ " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energyperdayinkwh\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionDayEuro" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per day " + ld.getLocation().getName()
+ " [%.2f €]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energyperdayineuro\"}\n");
} else if (LogicalDevice.Type_TwoWayMeterEnergyFeedSensor.equals(ld.getType())) {
validParams = "totalenergy, energypermonthinkwh, energypermonthineuro, energyperdayinkwh, energyperdayineuro";
exampleConfig.add("Number\trweEnergyFeedTotal" + ld.getId().substring(30) + "\t\t\"EnergyFeed total "
+ ld.getLocation().getName() + " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=totalenergy\"}\n");
exampleConfig
.add("Number\trweEnergyFeedMonthKWh" + ld.getId().substring(30) + "\t\t\"EnergyFeed per month "
+ ld.getLocation().getName() + " [%.3f kWh]\"\t<energy>\t(rwe) {"
+ context.getBindingType() + "=\"id=" + ld.getId() + ",param=energypermonthinkwh\"}\n");
exampleConfig.add("Number\trweEnergyFeedMonthEuro" + ld.getId().substring(30)
+ "\t\t\"EnergyFeed per month " + ld.getLocation().getName() + " [%.2f €]\"\t<energy>\t(rwe) {"
+ context.getBindingType() + "=\"id=" + ld.getId() + ",param=energypermonthineuro\"}\n");
exampleConfig.add("Number\trweEnergyFeedDayKWh" + ld.getId().substring(30) + "\t\t\"EnergyFeed per day "
+ ld.getLocation().getName() + " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=energyperdayinkwh\"}\n");
exampleConfig.add("Number\trweEnergyFeedDayEuro" + ld.getId().substring(30)
+ "\t\t\"EnergyFeed per day " + ld.getLocation().getName() + " [%.2f €]\"\t<energy>\t(rwe) {"
+ context.getBindingType() + "=\"id=" + ld.getId() + ",param=energyperdayineuro\"}\n");
} else if (LogicalDevice.Type_TwoWayMeterPowerConsumptionSensor.equals(ld.getType())) {
validParams = "powerinwatt";
exampleConfig.add("Number\trwePowerConsumption" + ld.getId().substring(30) + "\t\t\"PowerConsumption"
+ ld.getLocation().getName() + " [%.2f W]\"\t<energy>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=powerinwatt\"}\n");
// RWE Power Control
} else if (LogicalDevice.Type_PowerConsumptionSensor.equals(ld.getType())) {
validParams = "powerinwatt";
exampleConfig.add("Number\trwePowerConsumption" + ld.getId().substring(30) + "\t\t\"PowerConsumption"
+ ld.getLocation().getName() + " [%.2f W]\"\t<energy>\t(rwe) {" + context.getBindingType()
+ "=\"id=" + ld.getId() + ",param=powerinwatt\"}\n");
} else if (LogicalDevice.Type_EnergyConsumptionSensor.equals(ld.getType())) {
validParams = "totalenergy, energypermonthinkwh, energypermonthineuro, energyperdayinkwh, energyperdayineuro";
exampleConfig.add("Number\trweEnergyConsumptionTotal" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption total " + ld.getLocation().getName()
+ " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=totalenergy\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionMonthKWh" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per month " + ld.getLocation().getName()
+ " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energypermonthinkwh\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionMonthEuro" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per month " + ld.getLocation().getName()
+ " [%.2f €]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energypermonthineuro\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionDayKWh" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per day " + ld.getLocation().getName()
+ " [%.3f kWh]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energyperdayinkwh\"}\n");
exampleConfig.add("Number\trweEnergyConsumptionDayEuro" + ld.getId().substring(30)
+ "\t\t\"EnergyConsumption per day " + ld.getLocation().getName()
+ " [%.2f €]\"\t<energy>\t(rwe) {" + context.getBindingType() + "=\"id=" + ld.getId()
+ ",param=energyperdayineuro\"}\n");
} else if (LogicalDevice.Type_ThermostatActuator.equals(ld.getType())) {
continue; // ignore
} else {
validParams = "UNKNOWN";
}
if ("UNKNOWN".equals(validParams)) {
logger.debug("Found unsupported {} {} ({}/{}).", ld.getType(), ld.getId(), ld.getLocation().getName(),
ld.getName());
} else {
logger.info("Found {} {} ({}/{}). Valid params: {}", ld.getType(), ld.getId(),
ld.getLocation().getName(), ld.getName(), validParams);
}
}
Collections.sort(exampleConfig);
exampleConfig.add(0, "Group rwe\n");
logger.info("Example configuration for RWE Smarthome items:\n" + StringUtils.join(exampleConfig, ""));
}
/**
* Returns true, if the communicator is already running and false, if not.
*
* @return boolean
*/
public boolean isRunning() {
return rweSmarthomeSession != null;
}
/**
* load the state of the logical devices from RWE Smarthome SHC.
*
* This is only necessary, when the RWE binding is started and the states unknown or
* if the binding configuration has changed. Standard device state changes are
* propagated using poll().
*/
public void loadDeviceStates() {
try {
refreshLogicalDeviceStates();
logger.info("LogicalDevice states refreshed.");
} catch (RWESmarthomeSessionExpiredException e) {
logger.info("Session expired!" + e.getMessage());
try {
rweSmarthomeSession.logon(context.getConfig().getUsername(), context.getConfig().getPassword(),
context.getConfig().getHost());
logger.info("Login successful.");
// trigger refresh again as we had to login again...
context.setBindingChanged(true);
} catch (Exception e1) {
logger.error("Could not recover session with RWE Smarthome: " + e1.getMessage(), e1);
stop();
}
}
}
/**
* Polls for notifications and handles
*/
public void poll() {
if (!runPoller) {
return;
}
// Exit, if there is no valid session id
if (!context.getRweSmarthomeSession().isValid()) {
logger.debug("Invalid session, getNotifications aborted.");
return;
}
try {
getNotifications();
lastEventTime = System.currentTimeMillis();
} catch (LogoutNotificationException e) {
// restart communicator to get back a valid session
logger.info("Session expired!" + e.getMessage());
stop();
start();
} catch (RWESmarthomeSessionExpiredException e) {
// restart communicator to get back a valid session
logger.info("Session expired!" + e.getMessage());
stop();
start();
} catch (ConfigurationChangedException e) {
// restart communicator to rebuild everything
logger.info("Need to restart RWE Smarthome communicator: " + e.getMessage());
stop();
start();
}
}
/**
* Sends a command to an item
*
* @param itemName
* @param command
*/
public void sendCommand(String itemName, Command command) {
try {
for (RWESmarthomeBindingProvider provider : context.getProviders()) {
RWESmarthomeBindingConfig config = provider.getBindingConfigFor(itemName);
// SWITCH
if ("switch".equals(config.getDeviceParam())) {
boolean on = command.equals(OnOffType.ON);
logger.debug("Switching '{}' to '{}'", itemName, command);
setSwitchActuatorState(config.getDeviceId(), on);
// SETTEMPERATURE
} else if ("settemperature".equals(config.getDeviceParam())) {
logger.debug("Setting temperature for '{}' to '{}'.", itemName, command);
setTemperatureActuatorState(config.getDeviceId(), command.toString());
// OPERATIONMODEAUTO
} else if ("operationmodeauto".equals(config.getDeviceParam())) {
boolean opModeAuto = command.equals(OnOffType.ON);
logger.debug("Setting operationmode for '{}' to '{}'.", itemName,
opModeAuto ? RoomTemperatureActuator.OPERATION_MODE_AUTO
: RoomTemperatureActuator.OPERATION_MODE_MANUAL);
setRoomTemperatureActuatorOperationModeToAuto(config.getDeviceId(), opModeAuto);
// DIMMER
} else
if ("dimmer".equals(config.getDeviceParam()) || "dimmerinverted".equals(config.getDeviceParam())) {
Integer val = getPercentageValueFromCommand(command,
"dimmerinverted".equals(config.getDeviceParam()));
if (val == null) {
continue;
}
logger.debug("Setting dimmer '{}' to '{}'.", itemName, val);
setDimmerState(config.getDeviceId(), val.toString());
// ROLLERSHUTTER
} else if ("rollershutter".equals(config.getDeviceParam())
|| "rollershutterinverted".equals(config.getDeviceParam())) {
Integer val = getPercentageValueFromCommand(command,
"rollershutterinverted".equals(config.getDeviceParam()));
if (val == null) {
continue;
}
logger.debug("Setting rollershutter '{}' to '{}'.", itemName, val);
setRollershutterState(config.getDeviceId(), val.toString());
// ALARM
} else if ("alarm".equals(config.getDeviceParam())) {
boolean on = command.equals(OnOffType.ON);
logger.debug("Switching alarm '{}' to '{}'", itemName, command);
setAlarmActuatorState(config.getDeviceId(), on);
// VARIABLE
} else if ("variable".equals(config.getDeviceParam())) {
boolean on = command.equals(OnOffType.ON);
logger.debug("Switching variable '{}' to '{}'", itemName, command);
setVariableState(config.getDeviceId(), on);
}
}
} catch (RWESmarthomeSessionExpiredException e) {
logger.info("Session expired while executing command '{}' for item '{}'. Restart binding...", command,
itemName);
stop();
start();
logger.info("Retrying command '{}' for item '{}'...", command, itemName);
sendCommand(itemName, command);
}
}
/**
* Returns a percentage value as integer for a given command.
*
* Command types increase/decrease are not supported and lead to the return of null.
* If inverted is true, the returned value will be inverted (e.g. 40% -> 60%).
*
* @param command
* @param inverted
* @return integer or null
*/
private Integer getPercentageValueFromCommand(Command command, boolean inverted) {
Integer val;
if (command.equals(OnOffType.ON) || command.equals(UpDownType.DOWN)) {
val = 100;
} else if (command.equals(OnOffType.OFF) || command.equals(UpDownType.UP)) {
val = 0;
} else if (command instanceof IncreaseDecreaseType || command instanceof StopMoveType) {
logger.info(
"Command '{}' not implemented for dimmer/rollershutter. Must be handled within a rule, see binding documentation.",
command.toString());
return null;
} else {
val = new Integer(command.toString());
}
if (inverted || command instanceof UpDownType) { // always invert up/down commands
val = 100 - val;
}
return val;
}
/**
* Subscribes for notifications.
*
* Should be called once before getNotifications(). Times out after a couple of hours. So make sure to
* test against LogoutNotification and resubscribe.
*
* @throws RWESmarthomeSessionExpiredException
*/
public void subscribeForNotifications(String notificationType) throws RWESmarthomeSessionExpiredException {
String sResponse = "";
final String NOTIFICATION_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"NotificationRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\">"
+ "<Action>Subscribe</Action>" + "<NotificationType>%s</NotificationType>" + "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), notificationType);
logger.debug("REQ: " + NOTIFICATION_REQUEST);
sResponse = rweSmarthomeSession.executeRequest(NOTIFICATION_REQUEST, "/cmd");
logger.debug("SubscribeForNotification-Response: " + sResponse);
}
/**
* Subscribes for configuration change notifications.
*
* @throws RWESmarthomeSessionExpiredException
*/
public void subscribeForConfigurationChanges() throws RWESmarthomeSessionExpiredException {
subscribeForNotifications("ConfigurationChanges");
}
/**
* Subscribes for calibration notifications.
*
* @throws RWESmarthomeSessionExpiredException
*/
public void subscribeForCalibration() throws RWESmarthomeSessionExpiredException {
subscribeForNotifications("Calibration");
}
/**
* Subscribes for custom application notifications.
*
* @throws RWESmarthomeSessionExpiredException
*/
public void subscribeForCustomApplication() throws RWESmarthomeSessionExpiredException {
subscribeForNotifications("CustomApplication");
}
/**
* Subscribes for device state changes.
*
* @throws RWESmarthomeSessionExpiredException
*/
public void subscribeForDeviceStateChanges() throws RWESmarthomeSessionExpiredException {
subscribeForNotifications("DeviceStateChanges");
}
/**
* Subscribes for deployment changes.
*
* @throws RWESmarthomeSessionExpiredException
*/
public void subscribeForDeploymentChanges() throws RWESmarthomeSessionExpiredException {
subscribeForNotifications("DeploymentChanges");
}
/**
* Subscribes for message updates.
*
* @throws RWESmarthomeSessionExpiredException
*/
public void subscribeForMessageUpdates() throws RWESmarthomeSessionExpiredException {
subscribeForNotifications("MessageUpdates");
}
/**
* Refresh configuration.
*
* @return the RWE Smarthome configuration XML response
* @throws RWESmarthomeSessionExpiredException
* the smart home session expired exception
*/
public String refreshConfiguration() throws RWESmarthomeSessionExpiredException {
String sResponse = "";
final String GET_CONFIGURATION_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"GetEntitiesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\">\n"
+ "<EntityType>Configuration</EntityType>" + "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId());
sResponse = rweSmarthomeSession.executeRequest(GET_CONFIGURATION_REQUEST, "/cmd");
try {
GetEntitiesXMLResponse entitiesXMLRes = new GetEntitiesXMLResponse(
IOUtils.toInputStream(sResponse, "UTF8"));
rweSmarthomeSession.setLocations(entitiesXMLRes.getLocations());
rweSmarthomeSession.setLogicalDevices(entitiesXMLRes.getLogicalDevices());
rweSmarthomeSession.setCurrentConfigurationVersion(entitiesXMLRes.getConfigurationVersion());
} catch (IOException e) {
throw new RWESmarthomeSessionExpiredException(e);
}
return sResponse;
}
/**
* Refresh logical device state.
*
* @return the string
* @throws SmartHomeSessionExpiredException
* the smart home session expired exception
*/
public String refreshLogicalDeviceStates() throws RWESmarthomeSessionExpiredException {
String sResponse = "";
final String GET_ALL_LOGICAL_DEVICE_STATES_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"GetAllLogicalDeviceStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\" />",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion());
sResponse = rweSmarthomeSession.executeRequest(GET_ALL_LOGICAL_DEVICE_STATES_REQUEST, "/cmd");
try {
GetAllLogicalDeviceStatesXMLResponse entitiesXMLRes = new GetAllLogicalDeviceStatesXMLResponse(
IOUtils.toInputStream(sResponse, "UTF8"));
} catch (IOException e) {
throw new RWESmarthomeSessionExpiredException(e);
}
logger.debug("Refresh LD Response: " + sResponse);
return sResponse;
}
/**
* Gets the notifications.
*
* @return
*
* @return the XML response
* @throws SmartHomeSessionExpiredException
* the smart home session expired exception
* @throws LogoutNotificationException, SmartHomeSessionExpiredException
* @throws ConfigurationChangedException
*/
public String getNotifications()
throws LogoutNotificationException, RWESmarthomeSessionExpiredException, ConfigurationChangedException {
String sResponse = getNotificationsRequest();
// check for logout first
if (sResponse.contains("LogoutNotification") || sResponse.contains("ConfigurationChangedNotification")) {
// logout from notification updates received
NotificationsXMLResponse notXmlRes = new NotificationsXMLResponse(IOUtils.toInputStream(sResponse));
}
// as the XML format is almost the same, we can reuse GetAllLogicalDeviceStatesXMLResponse
// for the LogicalDevicesStatesChangedNotification
GetAllLogicalDeviceStatesXMLResponse logDevXmlRes = new GetAllLogicalDeviceStatesXMLResponse(
IOUtils.toInputStream(sResponse));
logger.trace("Notifications: {}", sResponse);
return sResponse;
}
/**
* Sends the getNotificationsRequest.
*
* @return the XML response
* @throws RWESmarthomeSessionExpiredException
*/
public String getNotificationsRequest() throws RWESmarthomeSessionExpiredException {
return rweSmarthomeSession.executeRequest("upd", "/upd");
}
/**
* Switch actuator change state.
*
* @param deviceId
* the device id
* @param on
* the new switchstate
* @throws RWESmarthomeSessionExpiredException
* the smart home session expired exception
*/
public void setSwitchActuatorState(String deviceId, boolean on) throws RWESmarthomeSessionExpiredException {
final String SWITCH_ON_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"SetActuatorStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\">"
+ "<ActuatorStates>"
+ "<LogicalDeviceState xsi:type=\"SwitchActuatorState\" LID=\"%s\" IsOn=\"%s\" />"
+ "</ActuatorStates>" + "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion(), deviceId, on);
String response = rweSmarthomeSession.executeRequest(SWITCH_ON_REQUEST, "/cmd");
if (!response.contains("Result=\"Ok\"")) {
logger.warn("Response not ok: " + response);
}
}
/**
* Changes the temperature of a RoomTemperatureActuator
*
* @param deviceId
* @param temperature
* @throws RWESmarthomeSessionExpiredException
*/
public void setTemperatureActuatorState(String deviceId, String temperature)
throws RWESmarthomeSessionExpiredException {
final String TEMPERATURE_CHANGE_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"SetActuatorStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\">"
+ "<ActuatorStates>"
+ "<LogicalDeviceState xsi:type=\"RoomTemperatureActuatorState\" LID=\"%s\" PtTmp=\"%s\" OpnMd=\"Auto\" WRAc=\"False\" />"
+ "</ActuatorStates></BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion(), deviceId,
temperature);
String response = rweSmarthomeSession.executeRequest(TEMPERATURE_CHANGE_REQUEST, "/cmd");
if (!response.contains("Result=\"Ok\"")) {
logger.warn("Response not ok: " + response);
}
}
/**
* Set the operation mode of a TemperaturActuator to "Auto" if true, "Manu" if false.
*
* @param deviceId
* @param operationModeAuto
* @throws RWESmarthomeSessionExpiredException
*/
public void setRoomTemperatureActuatorOperationModeToAuto(String deviceId, Boolean operationModeAuto)
throws RWESmarthomeSessionExpiredException {
final String OPERATION_MODE_CHANGE_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"SetActuatorStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\">"
+ "<ActuatorStates>"
+ "<LogicalDeviceState xsi:type=\"RoomTemperatureActuatorState\" LID=\"%s\" OpnMd=\"%s\" />"
+ "</ActuatorStates>" + "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion(), deviceId,
(operationModeAuto ? RoomTemperatureActuator.OPERATION_MODE_AUTO
: RoomTemperatureActuator.OPERATION_MODE_MANUAL));
String response = rweSmarthomeSession.executeRequest(OPERATION_MODE_CHANGE_REQUEST, "/cmd");
if (!response.contains("Result=\"Ok\"")) {
logger.warn("Response not ok: " + response);
}
}
/**
* Changes the alarm state
*
* @param deviceId
* @param on
* @throws RWESmarthomeSessionExpiredException
*/
public void setAlarmActuatorState(String deviceId, boolean on) throws RWESmarthomeSessionExpiredException {
final String CHANGE_ALARM_ACTUATOR_CHANGE_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"SetActuatorStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\">"
+ "<ActuatorStates>" + "<LogicalDeviceState xsi:type=\"AlarmActuatorState\" LID=\"%s\">"
+ "<IsOn>%s</IsOn>" + "</LogicalDeviceState>" + "</ActuatorStates>" + "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion(), deviceId, on);
String response = rweSmarthomeSession.executeRequest(CHANGE_ALARM_ACTUATOR_CHANGE_REQUEST, "/cmd");
if (!response.contains("Result=\"Ok\"")) {
logger.warn("Response not ok: " + response);
}
}
/**
* Change the state of a variable.
*
* @param deviceId
* @param on
* @throws RWESmarthomeSessionExpiredException
*/
public void setVariableState(String deviceId, boolean on) throws RWESmarthomeSessionExpiredException {
final String CHANGE_VARIABLE_STATE_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"SetActuatorStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\">"
+ "<ActuatorStates>" + "<LogicalDeviceState xsi:type=\"GenericDeviceState\" LID=\"%s\">"
+ "<Ppts>" + "<Ppt xsi:type=\"BooleanProperty\" Name=\"Value\" Value=\"%s\" />" + "</Ppts>"
+ "</LogicalDeviceState>" + "</ActuatorStates>" + "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion(), deviceId, on);
String response = rweSmarthomeSession.executeRequest(CHANGE_VARIABLE_STATE_REQUEST, "/cmd");
if (!response.contains("Result=\"Ok\"")) {
logger.warn("Response not ok: " + response);
}
}
/**
* Sets a dimmer to a new value.
*
* @param deviceId
* @param newValue
* @throws RWESmarthomeSessionExpiredException
*/
public void setDimmerState(String deviceId, String newValue) throws RWESmarthomeSessionExpiredException {
final String SWITCH_DIMMER_STATE_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"SetActuatorStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\">"
+ "<ActuatorStates>"
+ "<LogicalDeviceState xsi:type=\"DimmerActuatorState\" LID=\"%s\" DmLvl=\"%s\" />"
+ "</ActuatorStates>" + "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion(), deviceId,
newValue);
String response = rweSmarthomeSession.executeRequest(SWITCH_DIMMER_STATE_REQUEST, "/cmd");
if (!response.contains("Result=\"Ok\"")) {
logger.warn("Response not ok: " + response);
}
}
/**
* Sets the rollershutter to a new value.
*
* @param deviceId
* @param newValue
* @throws RWESmarthomeSessionExpiredException
*/
public void setRollershutterState(String deviceId, String newValue) throws RWESmarthomeSessionExpiredException {
final String CHANGE_ROLLERSHUTTER_STATE_REQUEST = String.format(
"<BaseRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"SetActuatorStatesRequest\" Version=\"%s\" RequestId=\"%s\" SessionId=\"%s\" BasedOnConfigVersion=\"%s\">"
+ "<ActuatorStates>" + "<LogicalDeviceState xsi:type=\"RollerShutterActuatorState\" LID=\"%s\">"
+ "<ShutterLevel>%s</ShutterLevel>" + "</LogicalDeviceState>" + "</ActuatorStates>"
+ "</BaseRequest>",
RWESmarthomeSession.getFirmwareVersion(), rweSmarthomeSession.getRequestId(),
rweSmarthomeSession.getSessionId(), rweSmarthomeSession.getCurrentConfigurationVersion(), deviceId,
newValue);
String response = rweSmarthomeSession.executeRequest(CHANGE_ROLLERSHUTTER_STATE_REQUEST, "/cmd");
if (!response.contains("Result=\"Ok\"")) {
logger.warn("Response not ok: " + response);
}
}
}