Skip to content

Commit

Permalink
Homematic: some updates (openhab#2231)
Browse files Browse the repository at this point in the history
* Optimized ThingHandler
* Fixed virtual datapoint handling when loading values
* Added jalousie channel type
* Refactored RPC server
* Refactored rpc server #2
* Fixed some type warnings
* Added virtual datapoint for HMW-IO-12-Sw14-DR device
* Initialize Thing even if it is offline
* Removed unnecessary try finally blocks
* Optimized trace logging

Signed-off-by: Gerhard Riegler <[email protected]>
  • Loading branch information
gerrieg authored and martinvw committed May 5, 2017
1 parent 77e0388 commit 382b323
Show file tree
Hide file tree
Showing 23 changed files with 446 additions and 348 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
package org.openhab.binding.homematic.converter.type;

import static org.openhab.binding.homematic.internal.misc.HomematicConstants.CHANNEL_TYPE_BLIND;
import static org.openhab.binding.homematic.internal.misc.HomematicConstants.*;

import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType;
import org.eclipse.smarthome.core.library.types.OnOffType;
Expand Down Expand Up @@ -113,6 +113,7 @@ protected PercentType fromBinding(HmDatapoint dp) throws ConverterException {
* Returns true, if the device of the datapoint is a rollershutter.
*/
private boolean isRollerShutter(HmDatapoint dp) {
return dp.getChannel().getType().equals(CHANNEL_TYPE_BLIND);
return dp.getChannel().getType().equals(CHANNEL_TYPE_BLIND)
|| dp.getChannel().getType().equals(CHANNEL_TYPE_JALOUSIE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,32 +77,29 @@ public void run() {
HmChannel channelZero = device.getChannel(0);
loadHomematicChannelValues(channelZero);
updateStatus(device);
if (!device.isOffline()) {
logger.debug("Initializing thing '{}' from gateway '{}'", getThing().getUID(), gateway.getId());

// update properties
Map<String, String> properties = editProperties();
setProperty(properties, channelZero, PROPERTY_BATTERY_TYPE,
VIRTUAL_DATAPOINT_NAME_BATTERY_TYPE);
setProperty(properties, channelZero, Thing.PROPERTY_FIRMWARE_VERSION,
VIRTUAL_DATAPOINT_NAME_FIRMWARE);
setProperty(properties, channelZero, Thing.PROPERTY_SERIAL_NUMBER, device.getAddress());
setProperty(properties, channelZero, PROPERTY_AES_KEY, DATAPOINT_NAME_AES_KEY);
updateProperties(properties);

// update configurations
Configuration config = editConfiguration();
for (HmChannel channel : device.getChannels()) {
for (HmDatapoint dp : channel.getDatapoints().values()) {
if (dp.getParamsetType() == HmParamsetType.MASTER) {
loadHomematicChannelValues(dp.getChannel());
config.put(MetadataUtils.getParameterName(dp),
dp.isEnumType() ? dp.getOptionValue() : dp.getValue());
}
logger.debug("Initializing thing '{}' from gateway '{}'", getThing().getUID(), gateway.getId());

// update properties
Map<String, String> properties = editProperties();
setProperty(properties, channelZero, PROPERTY_BATTERY_TYPE, VIRTUAL_DATAPOINT_NAME_BATTERY_TYPE);
setProperty(properties, channelZero, Thing.PROPERTY_FIRMWARE_VERSION,
VIRTUAL_DATAPOINT_NAME_FIRMWARE);
setProperty(properties, channelZero, Thing.PROPERTY_SERIAL_NUMBER, device.getAddress());
setProperty(properties, channelZero, PROPERTY_AES_KEY, DATAPOINT_NAME_AES_KEY);
updateProperties(properties);

// update configurations
Configuration config = editConfiguration();
for (HmChannel channel : device.getChannels()) {
for (HmDatapoint dp : channel.getDatapoints().values()) {
if (dp.getParamsetType() == HmParamsetType.MASTER) {
loadHomematicChannelValues(dp.getChannel());
config.put(MetadataUtils.getParameterName(dp),
dp.isEnumType() ? dp.getOptionValue() : dp.getValue());
}
}
updateConfiguration(config);
}
updateConfiguration(config);
} catch (HomematicClientException ex) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, ex.getMessage());
} catch (IOException ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.openhab.binding.homematic.internal.communicator.virtual.DisplayOptionsVirtualDatapointHandler;
import org.openhab.binding.homematic.internal.communicator.virtual.DisplayTextVirtualDatapoint;
import org.openhab.binding.homematic.internal.communicator.virtual.FirmwareVirtualDatapointHandler;
import org.openhab.binding.homematic.internal.communicator.virtual.HmwIoModuleVirtualDatapointHandler;
import org.openhab.binding.homematic.internal.communicator.virtual.InstallModeDurationVirtualDatapoint;
import org.openhab.binding.homematic.internal.communicator.virtual.InstallModeVirtualDatapoint;
import org.openhab.binding.homematic.internal.communicator.virtual.OnTimeAutomaticVirtualDatapointHandler;
Expand Down Expand Up @@ -82,7 +83,7 @@ public abstract class AbstractHomematicGateway implements RpcEventListener, Home
private static final long CONNECTION_TRACKER_INTERVAL_SECONDS = 15;
private static final String GATEWAY_POOL_NAME = "homematicGateway";

private Map<TransferMode, RpcClient> rpcClients = new HashMap<TransferMode, RpcClient>();
private Map<TransferMode, RpcClient<?>> rpcClients = new HashMap<TransferMode, RpcClient<?>>();
private Map<TransferMode, RpcServer> rpcServers = new HashMap<TransferMode, RpcServer>();

protected HomematicConfig config;
Expand Down Expand Up @@ -117,6 +118,7 @@ public abstract class AbstractHomematicGateway implements RpcEventListener, Home
virtualDatapointHandlers.add(new StateContactVirtualDatapointHandler());
virtualDatapointHandlers.add(new SignalStrengthVirtualDatapointHandler());
virtualDatapointHandlers.add(new DisplayTextVirtualDatapoint());
virtualDatapointHandlers.add(new HmwIoModuleVirtualDatapointHandler());
}

public AbstractHomematicGateway(String id, HomematicConfig config, HomematicGatewayListener eventListener) {
Expand Down Expand Up @@ -174,7 +176,6 @@ public void initialize() throws IOException {
startClients();
startServers();
startWatchdogs();
initialized = true;
}

/**
Expand Down Expand Up @@ -209,7 +210,7 @@ protected void startClients() throws IOException {
* Stops the Homematic gateway client.
*/
protected void stopClients() {
for (RpcClient rpcClient : rpcClients.values()) {
for (RpcClient<?> rpcClient : rpcClients.values()) {
rpcClient.dispose();
}
rpcClients.clear();
Expand Down Expand Up @@ -293,8 +294,8 @@ protected HmInterface getDefaultInterface() {
* {@inheritDoc}
*/
@Override
public RpcClient getRpcClient(HmInterface hmInterface) throws IOException {
RpcClient rpcClient = rpcClients.get(availableInterfaces.get(hmInterface));
public RpcClient<?> getRpcClient(HmInterface hmInterface) throws IOException {
RpcClient<?> rpcClient = rpcClients.get(availableInterfaces.get(hmInterface));
if (rpcClient == null) {
throw new IOException("RPC client for interface " + hmInterface + " not available");
}
Expand Down Expand Up @@ -421,6 +422,7 @@ public void loadAllDeviceMetadata() throws IOException {
if (!cancelLoadAllMetadata) {
devices.keySet().retainAll(loadedDevices);
}
initialized = true;
}

/**
Expand Down Expand Up @@ -869,7 +871,7 @@ private void validateConnection() throws IOException {
getRpcClient(getDefaultInterface()).validateConnection(getDefaultInterface());
} catch (IOException ex) {
// connection lost validation
RpcClient rpcClient = null;
RpcClient<?> rpcClient = null;
try {
if (config.getGatewayInfo().isHomegear() || config.getGatewayInfo().isCCU()) {
rpcClient = new BinRpcClient(config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static HomematicGateway createGateway(String id, HomematicConfig config,
* Loads some metadata about the type of the Homematic gateway.
*/
private static void loadGatewayInfo(HomematicConfig config, String id) throws IOException {
RpcClient rpcClient = new XmlRpcClient(config);
RpcClient<String> rpcClient = new XmlRpcClient(config);
try {
config.setGatewayInfo(rpcClient.getGatewayInfo(id));
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*
* @author Gerhard Riegler - Initial contribution
*/
public class BinRpcClient extends RpcClient {
public class BinRpcClient extends RpcClient<byte[]> {
private final Logger logger = LoggerFactory.getLogger(BinRpcClient.class);

private SocketHandler socketHandler;
Expand All @@ -46,7 +46,7 @@ public void dispose() {
* {@inheritDoc}
*/
@Override
protected RpcRequest createRpcRequest(String methodName) {
protected RpcRequest<byte[]> createRpcRequest(String methodName) {
return new BinRpcMessage(methodName, config.getEncoding());
}

Expand All @@ -71,7 +71,7 @@ public void init(HmInterface hmInterface, String clientId) throws IOException {
* Sends a BIN-RPC message and parses the response to see if there was an error.
*/
@Override
protected synchronized Object[] sendMessage(int port, RpcRequest request) throws IOException {
protected synchronized Object[] sendMessage(int port, RpcRequest<byte[]> request) throws IOException {
if (logger.isTraceEnabled()) {
logger.trace("Client BinRpcRequest:\n{}", request);
}
Expand All @@ -81,7 +81,7 @@ protected synchronized Object[] sendMessage(int port, RpcRequest request) throws
/**
* Sends the message, retries if there was an error.
*/
private Object[] sendMessage(int port, RpcRequest request, int rpcRetryCounter) throws IOException {
private Object[] sendMessage(int port, RpcRequest<byte[]> request, int rpcRetryCounter) throws IOException {
BinRpcMessage resp = null;
try {
Socket socket = socketHandler.getSocket(port);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
*
* @author Gerhard Riegler - Initial contribution
*/
public abstract class RpcClient {
public abstract class RpcClient<T> {
private final Logger logger = LoggerFactory.getLogger(RpcClient.class);
protected static final int MAX_RPC_RETRY = 1;

Expand All @@ -60,7 +60,7 @@ public RpcClient(HomematicConfig config) {
/**
* Returns a RpcRequest for this client.
*/
protected abstract RpcRequest createRpcRequest(String methodName);
protected abstract RpcRequest<T> createRpcRequest(String methodName);

/**
* Returns the callback url for this client.
Expand All @@ -70,13 +70,13 @@ public RpcClient(HomematicConfig config) {
/**
* Sends the RPC message to the gateway.
*/
protected abstract Object[] sendMessage(int port, RpcRequest request) throws IOException;
protected abstract Object[] sendMessage(int port, RpcRequest<T> request) throws IOException;

/**
* Register a callback for the specified interface where the Homematic gateway can send its events.
*/
public void init(HmInterface hmInterface, String clientId) throws IOException {
RpcRequest request = createRpcRequest("init");
RpcRequest<T> request = createRpcRequest("init");
request.addArg(getRpcCallbackUrl());
request.addArg(clientId);
sendMessage(config.getRpcPort(hmInterface), request);
Expand All @@ -86,7 +86,7 @@ public void init(HmInterface hmInterface, String clientId) throws IOException {
* Release a callback for the specified interface.
*/
public void release(HmInterface hmInterface) throws IOException {
RpcRequest request = createRpcRequest("init");
RpcRequest<T> request = createRpcRequest("init");
request.addArg(getRpcCallbackUrl());
sendMessage(config.getRpcPort(hmInterface), request);
}
Expand All @@ -95,23 +95,23 @@ public void release(HmInterface hmInterface) throws IOException {
* Returns all variable metadata and values from a Homegear gateway.
*/
public void getAllSystemVariables(HmChannel channel) throws IOException {
RpcRequest request = createRpcRequest("getAllSystemVariables");
RpcRequest<T> request = createRpcRequest("getAllSystemVariables");
new GetAllSystemVariablesParser(channel).parse(sendMessage(config.getRpcPort(channel), request));
}

/**
* Loads all device names from a Homegear gateway.
*/
public void loadDeviceNames(HmInterface hmInterface, Collection<HmDevice> devices) throws IOException {
RpcRequest request = createRpcRequest("getDeviceInfo");
RpcRequest<T> request = createRpcRequest("getDeviceInfo");
new HomegearLoadDeviceNamesParser(devices).parse(sendMessage(config.getRpcPort(hmInterface), request));
}

/**
* Returns true, if the interface is available on the gateway.
*/
public void checkInterface(HmInterface hmInterface) throws IOException {
RpcRequest request = createRpcRequest("init");
RpcRequest<T> request = createRpcRequest("init");
request.addArg("http://openhab.validation:1000");
sendMessage(config.getRpcPort(hmInterface), request);
}
Expand All @@ -120,31 +120,31 @@ public void checkInterface(HmInterface hmInterface) throws IOException {
* Validates the connection to the interface by calling the listBidcosInterfaces method.
*/
public void validateConnection(HmInterface hmInterface) throws IOException {
RpcRequest request = createRpcRequest("listBidcosInterfaces");
RpcRequest<T> request = createRpcRequest("listBidcosInterfaces");
sendMessage(config.getRpcPort(hmInterface), request);
}

/**
* Returns all script metadata from a Homegear gateway.
*/
public void getAllScripts(HmChannel channel) throws IOException {
RpcRequest request = createRpcRequest("getAllScripts");
RpcRequest<T> request = createRpcRequest("getAllScripts");
new GetAllScriptsParser(channel).parse(sendMessage(config.getRpcPort(channel), request));
}

/**
* Returns all device and channel metadata.
*/
public Collection<HmDevice> listDevices(HmInterface hmInterface) throws IOException {
RpcRequest request = createRpcRequest("listDevices");
RpcRequest<T> request = createRpcRequest("listDevices");
return new ListDevicesParser(hmInterface, config).parse(sendMessage(config.getRpcPort(hmInterface), request));
}

/**
* Loads all datapoint metadata into the given channel.
*/
public void addChannelDatapoints(HmChannel channel, HmParamsetType paramsetType) throws IOException {
RpcRequest request = createRpcRequest("getParamsetDescription");
RpcRequest<T> request = createRpcRequest("getParamsetDescription");
request.addArg(getRpcAddress(channel.getDevice().getAddress()) + ":" + channel.getNumber());
request.addArg(paramsetType.toString());
new GetParamsetDescriptionParser(channel, paramsetType).parse(sendMessage(config.getRpcPort(channel), request));
Expand All @@ -154,7 +154,7 @@ public void addChannelDatapoints(HmChannel channel, HmParamsetType paramsetType)
* Sets all datapoint values for the given channel.
*/
public void setChannelDatapointValues(HmChannel channel, HmParamsetType paramsetType) throws IOException {
RpcRequest request = createRpcRequest("getParamset");
RpcRequest<T> request = createRpcRequest("getParamset");
request.addArg(getRpcAddress(channel.getDevice().getAddress()) + ":" + channel.getNumber());
request.addArg(paramsetType.toString());
if (channel.getDevice().getHmInterface() == HmInterface.CUXD && paramsetType == HmParamsetType.VALUES) {
Expand Down Expand Up @@ -182,7 +182,7 @@ public void setChannelDatapointValues(HmChannel channel, HmParamsetType paramset
private void setChannelDatapointValues(HmChannel channel) throws IOException {
for (HmDatapoint dp : channel.getDatapoints().values()) {
if (dp.isReadable() && !dp.isVirtual() && dp.getParamsetType() == HmParamsetType.VALUES) {
RpcRequest request = createRpcRequest("getValue");
RpcRequest<T> request = createRpcRequest("getValue");
request.addArg(getRpcAddress(channel.getDevice().getAddress()) + ":" + channel.getNumber());
request.addArg(dp.getName());
new GetValueParser(dp).parse(sendMessage(config.getRpcPort(channel), request));
Expand All @@ -194,7 +194,7 @@ private void setChannelDatapointValues(HmChannel channel) throws IOException {
* Tries to identify the gateway and returns the GatewayInfo.
*/
public HmGatewayInfo getGatewayInfo(String id) throws IOException {
RpcRequest request = createRpcRequest("getDeviceDescription");
RpcRequest<T> request = createRpcRequest("getDeviceDescription");
request.addArg("BidCoS-RF");
GetDeviceDescriptionParser ddParser = new GetDeviceDescriptionParser();
ddParser.parse(sendMessage(config.getRpcPort(HmInterface.RF), request));
Expand Down Expand Up @@ -263,7 +263,7 @@ public void setDatapointValue(HmDatapoint dp, Object value) throws IOException {
value = ((Number) value).intValue();
}

RpcRequest request;
RpcRequest<T> request;
if (HmParamsetType.VALUES == dp.getParamsetType()) {
request = createRpcRequest("setValue");
request.addArg(getRpcAddress(dp.getChannel().getDevice().getAddress()) + ":" + dp.getChannel().getNumber());
Expand All @@ -284,7 +284,7 @@ public void setDatapointValue(HmDatapoint dp, Object value) throws IOException {
* Sets the value of a system variable on a Homegear gateway.
*/
public void setSystemVariable(HmDatapoint dp, Object value) throws IOException {
RpcRequest request = createRpcRequest("setSystemVariable");
RpcRequest<T> request = createRpcRequest("setSystemVariable");
request.addArg(dp.getInfo());
request.addArg(value);
sendMessage(config.getRpcPort(dp.getChannel()), request);
Expand All @@ -294,7 +294,7 @@ public void setSystemVariable(HmDatapoint dp, Object value) throws IOException {
* Executes a script on the Homegear gateway.
*/
public void executeScript(HmDatapoint dp) throws IOException {
RpcRequest request = createRpcRequest("runScript");
RpcRequest<T> request = createRpcRequest("runScript");
request.addArg(dp.getInfo());
sendMessage(config.getRpcPort(dp.getChannel()), request);
}
Expand All @@ -303,7 +303,7 @@ public void executeScript(HmDatapoint dp) throws IOException {
* Enables/disables the install mode for given seconds.
*/
public void setInstallMode(HmInterface hmInterface, boolean enable, int seconds) throws IOException {
RpcRequest request = createRpcRequest("setInstallMode");
RpcRequest<T> request = createRpcRequest("setInstallMode");
request.addArg(enable);
request.addArg(seconds);
request.addArg(1);
Expand All @@ -314,7 +314,7 @@ public void setInstallMode(HmInterface hmInterface, boolean enable, int seconds)
* Deletes the device from the gateway.
*/
public void deleteDevice(HmDevice device, int flags) throws IOException {
RpcRequest request = createRpcRequest("deleteDevice");
RpcRequest<T> request = createRpcRequest("deleteDevice");
request.addArg(device.getAddress());
request.addArg(flags);
sendMessage(config.getRpcPort(device.getHmInterface()), request);
Expand All @@ -334,7 +334,7 @@ private String getRpcAddress(String address) {
* Returns the rssi values for all devices.
*/
public List<HmRssiInfo> loadRssiInfo(HmInterface hmInterface) throws IOException {
RpcRequest request = createRpcRequest("rssiInfo");
RpcRequest<T> request = createRpcRequest("rssiInfo");
return new RssiInfoParser(config).parse(sendMessage(config.getRpcPort(hmInterface), request));
}

Expand Down
Loading

0 comments on commit 382b323

Please sign in to comment.