added migrated 2.x add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer
2020-09-21 01:58:32 +02:00
parent bbf1a7fd29
commit 6df6783b60
11662 changed files with 1302875 additions and 11 deletions

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.helios-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
<feature name="openhab-binding-helios" description="Helios Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle dependency="true">mvn:org.apache.ws.xmlschema/xmlschema-core/2.2.4</bundle>
<bundle dependency="true">mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.jaxws-api-2.2/2.9.0</bundle>
<bundle dependency="true">mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.saaj-api-1.3/2.9.0</bundle>
<bundle dependency="true">mvn:org.apache.cxf/cxf-core/3.1.14</bundle>
<bundle dependency="true">mvn:org.apache.cxf.services.wsn/cxf-services-wsn-api/3.1.14</bundle>
<bundle dependency="true">mvn:org.apache.felix/org.apache.felix.framework/6.0.2</bundle>
<bundle dependency="true">mvn:org.apache.geronimo.specs/geronimo-ws-metadata_2.0_spec/1.1.3</bundle>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.helios/${project.version}</bundle>
</feature>
</features>

View File

@@ -0,0 +1,72 @@
/**
* 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.helios.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link HeliosBinding} class defines common constants, which are used
* across the whole binding.
*
* @author Karel Goderis - Initial contribution
*/
@NonNullByDefault
public class HeliosBindingConstants {
public static final String BINDING_ID = "helios";
// List of all Thing Type UIDs
public static final ThingTypeUID HELIOS_VARIO_IP_2_7_TYPE = new ThingTypeUID(BINDING_ID, "ipvario27");
public static final ThingTypeUID HELIOS_VARIO_IP_2_21_TYPE = new ThingTypeUID(BINDING_ID, "ipvario221");
// List of all Channel ids
public static final String KEY_PRESSED = "keypressed";
public static final String KEY_PRESSED_STAMP = "keypressedstamp";
public static final String CALL_STATE = "callstate";
public static final String CALL_DIRECTION = "calldirection";
public static final String CALL_STATE_STAMP = "callstatestamp";
public static final String CARD = "card";
public static final String CARD_VALID = "cardvalid";
public static final String CARD_STAMP = "cardstamp";
public static final String CODE = "code";
public static final String CODE_VALID = "codevalid";
public static final String CODE_STAMP = "codestamp";
public static final String DEVICE_STATE = "devicestate";
public static final String DEVICE_STATE_STAMP = "devicestamp";
public static final String AUDIO_LOOP_TEST = "audiolooptest";
public static final String AUDIO_LOOP_TEST_STAMP = "audioloopteststamp";
public static final String MOTION = "motion";
public static final String MOTION_STAMP = "motionstamp";
public static final String NOISE = "noise";
public static final String NOISE_STAMP = "noisestamp";
public static final String KEY_RELEASED = "keyreleased";
public static final String KEY_RELEASED_STAMP = "keyreleasedstamp";
public static final String SWITCH_STATE = "switchstate";
public static final String SWITCH_STATE_ORIGINATOR = "switchstateoriginator";
public static final String SWITCH_STATE_SWITCH = "switchstateswitch";
public static final String SWITCH_STATE_STAMP = "switchstatestamp";
// List of all Channel type ids
public static final String SWITCH_ENABLER = "switchenabler";
public static final String SWITCH_TRIGGER = "switchtrigger";
public static final String IO_TRIGGER = "io";
// List of all Thing properties
public static final String VARIANT = "variant";
public static final String SERIAL_NUMBER = "serialNumber";
public static final String HW_VERSION = "hardwareVersion";
public static final String SW_VERSION = "softwareVersion";
public static final String BUILD_TYPE = "buildType";
public static final String DEVICE_NAME = "deviceName";
}

View File

@@ -0,0 +1,62 @@
/**
* 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.helios.internal;
import static org.openhab.binding.helios.internal.HeliosBindingConstants.*;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openhab.binding.helios.internal.handler.HeliosHandler221;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
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 HeliosHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @author Karel Goderis - Initial contribution
*/
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.helios")
public class HeliosHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(
Stream.of(HELIOS_VARIO_IP_2_7_TYPE, HELIOS_VARIO_IP_2_21_TYPE).collect(Collectors.toSet()));
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}
@Override
protected ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(HELIOS_VARIO_IP_2_7_TYPE)) {
return new HeliosHandler27(thing);
}
if (thingTypeUID.equals(HELIOS_VARIO_IP_2_21_TYPE)) {
return new HeliosHandler221(thing);
}
return null;
}
}

View File

@@ -0,0 +1,451 @@
/**
* 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.helios.internal.handler;
import static org.openhab.binding.helios.internal.HeliosBindingConstants.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.BindingType;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.wsn.wsdl.WSNWSDLLocator;
import org.oasis_open.docs.wsn.b_2.FilterType;
import org.oasis_open.docs.wsn.b_2.Notify;
import org.oasis_open.docs.wsn.b_2.Renew;
import org.oasis_open.docs.wsn.b_2.RenewResponse;
import org.oasis_open.docs.wsn.b_2.Subscribe;
import org.oasis_open.docs.wsn.b_2.SubscribeResponse;
import org.oasis_open.docs.wsn.b_2.TopicExpressionType;
import org.oasis_open.docs.wsn.b_2.Unsubscribe;
import org.oasis_open.docs.wsn.b_2.UnsubscribeResponse;
import org.oasis_open.docs.wsn.bw_2.InvalidFilterFault;
import org.oasis_open.docs.wsn.bw_2.InvalidMessageContentExpressionFault;
import org.oasis_open.docs.wsn.bw_2.InvalidProducerPropertiesExpressionFault;
import org.oasis_open.docs.wsn.bw_2.InvalidTopicExpressionFault;
import org.oasis_open.docs.wsn.bw_2.NotificationConsumer;
import org.oasis_open.docs.wsn.bw_2.NotificationProducer;
import org.oasis_open.docs.wsn.bw_2.NotifyMessageNotSupportedFault;
import org.oasis_open.docs.wsn.bw_2.PausableSubscriptionManager;
import org.oasis_open.docs.wsn.bw_2.SubscribeCreationFailedFault;
import org.oasis_open.docs.wsn.bw_2.TopicExpressionDialectUnknownFault;
import org.oasis_open.docs.wsn.bw_2.TopicNotSupportedFault;
import org.oasis_open.docs.wsn.bw_2.UnableToDestroySubscriptionFault;
import org.oasis_open.docs.wsn.bw_2.UnacceptableInitialTerminationTimeFault;
import org.oasis_open.docs.wsn.bw_2.UnacceptableTerminationTimeFault;
import org.oasis_open.docs.wsn.bw_2.UnrecognizedPolicyRequestFault;
import org.oasis_open.docs.wsn.bw_2.UnsupportedPolicyRequestFault;
import org.oasis_open.docs.wsrf.rw_2.ResourceUnknownFault;
import org.openhab.binding.helios.internal.ws.soap.SOAPActionHandler;
import org.openhab.binding.helios.internal.ws.soap.SOAPCallStateChanged;
import org.openhab.binding.helios.internal.ws.soap.SOAPCardEntered;
import org.openhab.binding.helios.internal.ws.soap.SOAPCodeEntered;
import org.openhab.binding.helios.internal.ws.soap.SOAPDeviceState;
import org.openhab.binding.helios.internal.ws.soap.SOAPEvent;
import org.openhab.binding.helios.internal.ws.soap.SOAPKeyPressed;
import org.openhab.binding.helios.internal.ws.soap.SOAPObjectFactory;
import org.openhab.binding.helios.internal.ws.soap.SOAPSubscriptionActionHandler;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.StringType;
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.types.Command;
import org.openhab.core.types.RefreshType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* The {@link HeliosHandler27} is responsible for handling commands, which are
* sent to one of the channels.
*
* @author Karel Goderis - Initial contribution
*/
@WebService(endpointInterface = "org.oasis_open.docs.wsn.bw_2.NotificationConsumer")
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public class HeliosHandler27 extends BaseThingHandler implements NotificationConsumer {
// List of Configuration constants
public static final String IP_ADDRESS = "ipAddress";
public static final String OPENHAB_IP_ADDRESS = "openHABipAddress";
public static final String OPENHAB_PORT_NUMBER = "openHABportNumber";
private final Logger logger = LoggerFactory.getLogger(HeliosHandler27.class);
private static final String SUBSCRIPTION_PERIOD = "PT1H";
private JAXBContext context = null;
private Endpoint endpoint = null;
private NotificationProducer notificationProducer = null;
private PausableSubscriptionManager subscription = null;
private GregorianCalendar currentTime;
private GregorianCalendar terminationTime;
private W3CEndpointReference subscriptionReference;
private String subscriptionID;
private SOAPEvent previousEvent = null;
public static final String HELIOS_URI = "http://www.2n.cz/2013/event";
public static final String DIALECT_URI = "http://www.2n.cz/2013/TopicExpression/Multiple";
public static final String WSN_URI = "http://docs.oasis-open.org/wsn/b-2";
public static final QName TOPIC_EXPRESSION = new QName(WSN_URI, "TopicExpression");
public static final QName INITIAL_TERMINATION_TIME = new QName(WSN_URI, "InitialTerminationTime");
public static final QName MAXIMUM_NUMBER = new QName(HELIOS_URI, "MaximumNumber");
public static final QName SIMPLE_MESSAGES = new QName(HELIOS_URI, "SimpleMessages");
public static final QName START_TIME_STAMP = new QName(HELIOS_URI, "StartTimestamp");
public static final QName START_RECORD_ID = new QName(HELIOS_URI, "StartRecordId");
public HeliosHandler27(Thing thing) {
super(thing);
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if (!(command instanceof RefreshType)) {
// 2N.cz has not yet released the automation part of the Helios IP HTTP/SOAP based API. Only the
// notification part has been documented, so for now there is nothing to do
// here
logger.debug("The Helios IP is a read-only device and can not handle commands");
}
}
public String getSubscriptionID() {
return subscriptionID;
}
@SuppressWarnings("rawtypes")
@Override
public void initialize() {
logger.debug("Initializing Helios IP handler.");
List<Handler> handlerChain = new ArrayList<>();
handlerChain.add(new SOAPActionHandler());
try {
context = JAXBContext.newInstance(SOAPObjectFactory.class, SOAPEvent.class, SOAPKeyPressed.class,
SOAPCallStateChanged.class, SOAPCodeEntered.class, SOAPCardEntered.class, SOAPDeviceState.class);
} catch (JAXBException e) {
logger.error("An exception occurred while setting up the JAXB Context factory: {}", e.getMessage(), e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
throw new RuntimeException();
}
try {
if (endpoint == null || (endpoint != null && !endpoint.isPublished())) {
String address = "http://" + (String) getConfig().get(OPENHAB_IP_ADDRESS) + ":"
+ ((BigDecimal) getConfig().get(OPENHAB_PORT_NUMBER)).toString() + "/notification"
+ System.currentTimeMillis();
logger.debug("Publishing the notification consumer webservice on '{}", address);
endpoint = Endpoint.publish(address, this);
((javax.xml.ws.soap.SOAPBinding) endpoint.getBinding()).setHandlerChain(handlerChain);
}
} catch (WebServiceException e1) {
logger.debug("An exception occurred while setting up the notification consumer webservice: {}",
e1.getMessage(), e1);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e1.getMessage());
return;
}
try {
String heliosAddress = "http://" + (String) getConfig().get(IP_ADDRESS) + "/notification";
Service notificationProducerService = Service.create(WSNWSDLLocator.getWSDLUrl(),
new QName("http://cxf.apache.org/wsn/jaxws", "NotificationProducerService"));
notificationProducer = notificationProducerService.getPort(
new W3CEndpointReferenceBuilder().address(heliosAddress).build(), NotificationProducer.class);
((BindingProvider) notificationProducer).getBinding().setHandlerChain(handlerChain);
} catch (WebServiceException e1) {
logger.debug("An exception occurred while setting up the notification webservice client: {}",
e1.getMessage(), e1);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e1.getMessage());
return;
}
try {
// set up the access to the subscription manager on the Helios IP
// Vario so that we can renew in the future
String heliosAddress = "http://" + (String) getConfig().get(IP_ADDRESS) + "/notification";
Service subscriptionService = Service.create(WSNWSDLLocator.getWSDLUrl(),
new QName("http://cxf.apache.org/wsn/jaxws", "PausableSubscriptionManagerService"));
subscription = subscriptionService.getPort(new W3CEndpointReferenceBuilder().address(heliosAddress).build(),
PausableSubscriptionManager.class);
handlerChain = new ArrayList<>();
handlerChain.add(new SOAPSubscriptionActionHandler(this));
((BindingProvider) subscription).getBinding().setHandlerChain(handlerChain);
} catch (WebServiceException e1) {
logger.debug("An exception occurred while setting up the subscription manager client: {}", e1.getMessage(),
e1);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e1.getMessage());
return;
}
try {
subscribe(endpoint.getEndpointReference(W3CEndpointReference.class));
} catch (WebServiceException | TopicNotSupportedFault | InvalidFilterFault | TopicExpressionDialectUnknownFault
| UnacceptableInitialTerminationTimeFault | SubscribeCreationFailedFault
| InvalidMessageContentExpressionFault | InvalidTopicExpressionFault | UnrecognizedPolicyRequestFault
| UnsupportedPolicyRequestFault | ResourceUnknownFault | NotifyMessageNotSupportedFault
| InvalidProducerPropertiesExpressionFault e) {
logger.debug("An exception occurred while subscribing to the notifications for thing '{}': {}",
getThing().getUID(), e.getMessage(), e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
return;
}
updateStatus(ThingStatus.ONLINE);
}
@Override
public void dispose() {
logger.debug("Disposing Helios IP handler.");
try {
unsubscribe();
if (endpoint != null) {
endpoint.stop();
}
endpoint = null;
terminationTime = null;
context = null;
notificationProducer = null;
subscription = null;
} catch (Exception e) {
logger.error("An exception occurred while disposing the Helios Thing Handler : {}", e.getMessage(), e);
}
}
@Override
public void notify(
@WebParam(partName = "Notify", name = "Notify", targetNamespace = "http://docs.oasis-open.org/wsn/b-2") Notify notify) {
for (Object object : notify.getAny()) {
try {
this.processNotification(context.createUnmarshaller().unmarshal((Element) object, SOAPEvent.class));
} catch (JAXBException e) {
logger.error("An exception occurred while processing a notification message : {}", e.getMessage(), e);
}
}
}
public void processNotification(JAXBElement<SOAPEvent> message) {
if (getThing().getStatus() == ThingStatus.ONLINE) {
SOAPEvent event = message.getValue();
// WS-Notification does not provide a mechanism to query existing
// subscriptions established before, so these keep lingering on the
// remote device. Therefore, when restarting the OH runtime, we
// might receive events more than one time, we need to filter these
// out
if (previousEvent == null || !previousEvent.equals(event)) {
previousEvent = event;
Object data = event.getData();
if (data instanceof SOAPKeyPressed) {
StringType valueType = new StringType(((SOAPKeyPressed) data).getKeyCode());
updateState(new ChannelUID(getThing().getUID(), KEY_PRESSED), valueType);
DateTimeType stampType = new DateTimeType(event.getTimestamp());
updateState(new ChannelUID(getThing().getUID(), KEY_PRESSED_STAMP), stampType);
}
if (data instanceof SOAPCallStateChanged) {
StringType valueType = new StringType(((SOAPCallStateChanged) data).getState());
updateState(new ChannelUID(getThing().getUID(), CALL_STATE), valueType);
valueType = new StringType(((SOAPCallStateChanged) data).getDirection());
updateState(new ChannelUID(getThing().getUID(), CALL_DIRECTION), valueType);
DateTimeType stampType = new DateTimeType(event.getTimestamp());
updateState(new ChannelUID(getThing().getUID(), CALL_STATE_STAMP), stampType);
}
if (data instanceof SOAPCardEntered) {
StringType valueType = new StringType(((SOAPCardEntered) data).getCard());
updateState(new ChannelUID(getThing().getUID(), CARD), valueType);
valueType = new StringType(((SOAPCardEntered) data).getValid());
updateState(new ChannelUID(getThing().getUID(), CARD_VALID), valueType);
DateTimeType stampType = new DateTimeType(event.getTimestamp());
updateState(new ChannelUID(getThing().getUID(), CARD_STAMP), stampType);
}
if (data instanceof SOAPCodeEntered) {
StringType valueType = new StringType(((SOAPCodeEntered) data).getCode());
updateState(new ChannelUID(getThing().getUID(), CODE), valueType);
valueType = new StringType(((SOAPCodeEntered) data).getValid());
updateState(new ChannelUID(getThing().getUID(), CODE_VALID), valueType);
DateTimeType stampType = new DateTimeType(event.getTimestamp());
updateState(new ChannelUID(getThing().getUID(), CODE_STAMP), stampType);
}
if (data instanceof SOAPDeviceState) {
StringType valueType = new StringType(((SOAPDeviceState) data).getState());
updateState(new ChannelUID(getThing().getUID(), DEVICE_STATE), valueType);
DateTimeType stampType = new DateTimeType(event.getTimestamp());
updateState(new ChannelUID(getThing().getUID(), DEVICE_STATE_STAMP), stampType);
}
} else {
logger.warn("Duplicate event received due to lingering subscriptions: '{}':'{}'", event.getEventName(),
event.getTimestamp());
}
}
}
public void renew(String newTerminationTime) throws ResourceUnknownFault, UnacceptableTerminationTimeFault {
if (subscription != null) {
Renew renew = new Renew();
renew.setTerminationTime(newTerminationTime);
RenewResponse response = subscription.renew(renew);
currentTime = response.getCurrentTime().toGregorianCalendar();
terminationTime = response.getTerminationTime().toGregorianCalendar();
SimpleDateFormat pFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
logger.debug("Renewed the subscription with ID '{}' for '{}' from {} until {}",
new Object[] { getSubscriptionID(), getThing().getUID(), pFormatter.format(currentTime.getTime()),
pFormatter.format(terminationTime.getTime()) });
}
}
public void unsubscribe() {
if (subscription != null) {
try {
UnsubscribeResponse response = subscription.unsubscribe(new Unsubscribe());
logger.debug("Unsubscribing the subscription with ID '{}' for '{}' ", getSubscriptionID(),
getThing().getUID());
} catch (UnableToDestroySubscriptionFault | ResourceUnknownFault e) {
logger.error("An exception occurred while unsubscribing from the subscription : {}", e.getMessage(), e);
}
}
}
public void subscribe(W3CEndpointReference epr)
throws TopicNotSupportedFault, InvalidFilterFault, TopicExpressionDialectUnknownFault,
UnacceptableInitialTerminationTimeFault, SubscribeCreationFailedFault, InvalidMessageContentExpressionFault,
InvalidTopicExpressionFault, UnrecognizedPolicyRequestFault, UnsupportedPolicyRequestFault,
ResourceUnknownFault, NotifyMessageNotSupportedFault, InvalidProducerPropertiesExpressionFault {
if (notificationProducer != null) {
Subscribe subscribeRequest = new Subscribe();
subscribeRequest.setConsumerReference(epr);
subscribeRequest.setFilter(new FilterType());
TopicExpressionType topicExp = new TopicExpressionType();
topicExp.getContent().add("");
topicExp.setDialect(DIALECT_URI);
subscribeRequest.getFilter().getAny()
.add(new JAXBElement<>(TOPIC_EXPRESSION, TopicExpressionType.class, topicExp));
subscribeRequest.setInitialTerminationTime(
new JAXBElement<>(INITIAL_TERMINATION_TIME, String.class, SUBSCRIPTION_PERIOD));
subscribeRequest.setSubscriptionPolicy(new Subscribe.SubscriptionPolicy());
subscribeRequest.getSubscriptionPolicy().getAny().add(new JAXBElement<>(MAXIMUM_NUMBER, Integer.class, 1));
subscribeRequest.getSubscriptionPolicy().getAny().add(new JAXBElement<>(SIMPLE_MESSAGES, Integer.class, 1));
GregorianCalendar now = new GregorianCalendar();
SimpleDateFormat pFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
subscribeRequest.getSubscriptionPolicy().getAny()
.add(new JAXBElement<>(START_TIME_STAMP, String.class, pFormatter.format(now.getTime())));
SubscribeResponse response = notificationProducer.subscribe(subscribeRequest);
if (response != null) {
currentTime = response.getCurrentTime().toGregorianCalendar();
terminationTime = response.getTerminationTime().toGregorianCalendar();
subscriptionReference = response.getSubscriptionReference();
Element element = DOMUtils.createDocument().createElement("elem");
subscriptionReference.writeTo(new DOMResult(element));
NodeList nl = element.getElementsByTagNameNS("http://www.2n.cz/2013/event", "SubscriptionId");
if (nl != null && nl.getLength() > 0) {
Element e = (Element) nl.item(0);
subscriptionID = DOMUtils.getContent(e).trim();
}
logger.debug("Established a subscription with ID '{}' for '{}' as from {} until {}",
new Object[] { subscriptionID, getThing().getUID(), pFormatter.format(currentTime.getTime()),
pFormatter.format(terminationTime.getTime()) });
java.util.Calendar triggerTime = terminationTime;
triggerTime.add(Calendar.MINUTE, -1);
logger.debug("Scheduling a renewal of the subscription with ID '{}' for '{}' to happen on {}",
new Object[] { subscriptionID, getThing().getUID(), pFormatter.format(triggerTime.getTime()) });
try {
scheduler.schedule(renewRunnable, triggerTime.getTimeInMillis() - System.currentTimeMillis(),
TimeUnit.MILLISECONDS);
} catch (RejectedExecutionException e) {
logger.error("An exception occurred while scheduling a renewal : '{}'", e.getMessage(), e);
}
}
}
}
protected Runnable renewRunnable = new Runnable() {
@Override
public void run() {
SimpleDateFormat pFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
boolean result = false;
try {
((HeliosHandler27) getThing().getHandler()).renew(SUBSCRIPTION_PERIOD);
result = true;
} catch (Exception e) {
logger.error("An exception occurred while renewing the subscription : {}", e.getMessage(), e);
((HeliosHandler27) getThing().getHandler()).dispose();
((HeliosHandler27) getThing().getHandler()).initialize();
return;
}
if (result) {
java.util.Calendar triggerTime = terminationTime;
triggerTime.add(Calendar.MINUTE, -1);
logger.debug("Scheduling a renewal of the subscription with ID '{}' for '{}' to happen on {}",
new Object[] { subscriptionID, getThing().getUID(), pFormatter.format(triggerTime.getTime()) });
try {
scheduler.schedule(renewRunnable, triggerTime.getTimeInMillis() - System.currentTimeMillis(),
TimeUnit.MILLISECONDS);
} catch (RejectedExecutionException e) {
logger.error("An exception occurred while scheduling a renewal : '{}'", e.getMessage(), e);
}
}
}
};
}

View File

@@ -0,0 +1,28 @@
/**
* 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.helios.internal.ws.rest;
/**
* Helper class for encapsulating REST objects
*
* @author Karel Goderis - Initial contribution
*/
public class RESTError {
public String code;
public String param;
public String description;
RESTError() {
}
}

View File

@@ -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.helios.internal.ws.rest;
import com.google.gson.JsonObject;
/**
* Helper class for encapsulating REST objects
*
* @author Karel Goderis - Initial contribution
*/
public class RESTEvent {
public long id;
public long utcTime;
public long upTime;
public String event;
public JsonObject params;
RESTEvent() {
}
}

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.helios.internal.ws.rest;
/**
* Helper class for encapsulating REST objects
*
* @author Karel Goderis - Initial contribution
*/
public class RESTPort {
public String port;
public String type;
RESTPort() {
}
}

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.helios.internal.ws.rest;
/**
* Helper class for encapsulating REST objects
*
* @author Karel Goderis - Initial contribution
*/
public class RESTSubscribeResponse {
public long id;
RESTSubscribeResponse() {
}
}

View File

@@ -0,0 +1,29 @@
/**
* 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.helios.internal.ws.rest;
/**
* Helper class for encapsulating REST objects
*
* @author Karel Goderis - Initial contribution
*/
public class RESTSwitch {
public long id;
public String enabled;
public String mode;
public long switchOnDuration;
public String type;
RESTSwitch() {
}
}

View File

@@ -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.helios.internal.ws.rest;
/**
* Helper class for encapsulating REST objects
*
* @author Karel Goderis - Initial contribution
*/
public class RESTSystemInfo {
public String variant;
public String serialNumber;
public String hwVersion;
public String swVersion;
public String buildType;
public String deviceName;
RESTSystemInfo() {
}
}

View File

@@ -0,0 +1,56 @@
/**
* 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.helios.internal.ws.soap;
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
/**
* The {@link SOAPActionHandler} is a custom SOAP handler that modifies some SOAP
* headers in order to get the Helios comm. working
*
* @author Karel Goderis - Initial contribution
*/
public class SOAPActionHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
// Nothing to do here
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// Nothing to do here
return false;
}
@Override
public void close(MessageContext context) {
// Nothing to do here
}
@Override
public Set<QName> getHeaders() {
Set<QName> set = new HashSet<>();
// Make sure the '[{http://www.w3.org/2005/08/addressing}]Action' header
// is handled in case the device set the 'MustUnderstand' attribute to
// '1'
set.add(new QName("http://www.w3.org/2005/08/addressing", "Action"));
return set;
}
}

View File

@@ -0,0 +1,52 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
/**
* Helios SOAP Protocol Message
*
* @author Karel Goderis - Initial contribution
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Data", namespace = HeliosHandler27.HELIOS_URI)
public class SOAPCallStateChanged extends SOAPDataField {
@XmlElement(name = "State", namespace = HeliosHandler27.HELIOS_URI)
protected String state;
@XmlElement(name = "Direction", namespace = HeliosHandler27.HELIOS_URI)
protected String direction;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
}

View File

@@ -0,0 +1,52 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
/**
* Helios SOAP Protocol Message
*
* @author Karel Goderis - Initial contribution
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Data", namespace = HeliosHandler27.HELIOS_URI)
public class SOAPCardEntered extends SOAPDataField {
@XmlElement(name = "Card", namespace = HeliosHandler27.HELIOS_URI)
protected String card;
@XmlElement(name = "Valid", namespace = HeliosHandler27.HELIOS_URI)
protected String valid;
public String getCard() {
return card;
}
public void setCard(String card) {
this.card = card;
}
public String getValid() {
return valid;
}
public void setValid(String valid) {
this.valid = valid;
}
}

View File

@@ -0,0 +1,52 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
/**
* Helios SOAP Protocol Message
*
* @author Karel Goderis - Initial contribution
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Data", namespace = HeliosHandler27.HELIOS_URI)
public class SOAPCodeEntered extends SOAPDataField {
@XmlElement(name = "Code", namespace = HeliosHandler27.HELIOS_URI)
protected String code;
@XmlElement(name = "Valid", namespace = HeliosHandler27.HELIOS_URI)
protected String valid;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getValid() {
return valid;
}
public void setValid(String valid) {
this.valid = valid;
}
}

View File

@@ -0,0 +1,24 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
/**
* Helios SOAP Protocol Message
*
* @author Karel Goderis - Initial contribution
*/
@XmlJavaTypeAdapter(SOAPDataFieldAdapter.class)
public abstract class SOAPDataField {
}

View File

@@ -0,0 +1,87 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
/**
* The {@link SOAPDataFieldAdapter} is a helper class that is used to
* unmarshal some 'variable' SOAP messages
*
* @author Karel Goderis - Initial contribution
*/
public class SOAPDataFieldAdapter extends XmlAdapter<SOAPDataFieldAdapter.AdaptedHeliosDataField, SOAPDataField> {
public static class AdaptedHeliosDataField {
@XmlElement
public String State;
@XmlElement
public String Direction;
@XmlElement
public String Code;
@XmlElement
public String Valid;
@XmlElement
public String Key;
@XmlElement
public String Card;
}
@Override
public AdaptedHeliosDataField marshal(SOAPDataField arg0) throws Exception {
return null;
}
@Override
public SOAPDataField unmarshal(AdaptedHeliosDataField arg0) throws Exception {
if (null == arg0) {
return null;
}
if (null != arg0.Card && null != arg0.Valid) {
SOAPCardEntered heliosCardEntered = new SOAPCardEntered();
heliosCardEntered.setCard(arg0.Card);
heliosCardEntered.setValid(arg0.Valid);
return heliosCardEntered;
}
if (null != arg0.Code && null != arg0.Valid) {
SOAPCodeEntered heliosCodeEntered = new SOAPCodeEntered();
heliosCodeEntered.setCode(arg0.Code);
heliosCodeEntered.setValid(arg0.Valid);
return heliosCodeEntered;
}
if (null != arg0.Key) {
SOAPKeyPressed heliosKeyPressed = new SOAPKeyPressed();
heliosKeyPressed.setKeyCode(arg0.Key);
return heliosKeyPressed;
}
if (null != arg0.State && null != arg0.Direction) {
SOAPCallStateChanged heliosCallStateChanged = new SOAPCallStateChanged();
heliosCallStateChanged.setState(arg0.State);
heliosCallStateChanged.setDirection(arg0.Direction);
return heliosCallStateChanged;
}
if (null != arg0.State) {
SOAPDeviceState heliosDeviceState = new SOAPDeviceState();
heliosDeviceState.setState(arg0.State);
return heliosDeviceState;
}
return null;
}
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.helios.internal.ws.soap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
/**
* Helios SOAP Protocol Message
*
* @author Karel Goderis - Initial contribution
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Data", namespace = HeliosHandler27.HELIOS_URI)
public class SOAPDeviceState extends SOAPDataField {
@XmlElement(name = "State", namespace = HeliosHandler27.HELIOS_URI)
protected String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}

View File

@@ -0,0 +1,108 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
/**
* Helios SOAP Protocol Message
*
* @author Karel Goderis - Initial contribution
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "HeliosEvent", namespace = HeliosHandler27.HELIOS_URI, propOrder = { "timestamp", "eventName", "data" })
@XmlRootElement(name = "Msg")
public class SOAPEvent {
@XmlElement(name = "Timestamp", namespace = HeliosHandler27.HELIOS_URI)
protected String timestamp;
@XmlElement(name = "EventName", namespace = HeliosHandler27.HELIOS_URI)
protected String eventName;
@XmlElement(name = "Data", namespace = HeliosHandler27.HELIOS_URI)
protected SOAPDataField data;
public SOAPDataField getData() {
return data;
}
public void setData(SOAPDataField data) {
this.data = data;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getEventName() {
return eventName;
}
public void setEventName(String eventName) {
this.eventName = eventName;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SOAPEvent)) {
return false;
}
if (obj == this) {
return true;
}
SOAPEvent event = (SOAPEvent) obj;
if (event.getEventName().equals(eventName) && event.getTimestamp().equals(timestamp)) {
Object eventData = event.getData();
if (data instanceof SOAPKeyPressed) {
return ((SOAPKeyPressed) data).getKeyCode().equals(((SOAPKeyPressed) eventData).getKeyCode());
}
if (data instanceof SOAPCallStateChanged) {
return ((SOAPCallStateChanged) data).getDirection()
.equals(((SOAPCallStateChanged) eventData).getDirection())
&& ((SOAPCallStateChanged) data).getState()
.equals(((SOAPCallStateChanged) eventData).getState());
}
if (data instanceof SOAPCardEntered) {
return ((SOAPCardEntered) data).getCard().equals(((SOAPCardEntered) eventData).getCard())
&& ((SOAPCardEntered) data).getValid().equals(((SOAPCardEntered) eventData).getValid());
}
if (data instanceof SOAPCodeEntered) {
return ((SOAPCodeEntered) data).getCode().equals(((SOAPCodeEntered) eventData).getCode())
&& ((SOAPCodeEntered) data).getValid().equals(((SOAPCodeEntered) eventData).getValid());
}
if (data instanceof SOAPDeviceState) {
return ((SOAPDeviceState) data).getState().equals(((SOAPDeviceState) eventData).getState());
}
}
return false;
}
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.helios.internal.ws.soap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
/**
* Helios SOAP Protocol Message
*
* @author Karel Goderis - Initial contribution
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Data", namespace = HeliosHandler27.HELIOS_URI)
public class SOAPKeyPressed extends SOAPDataField {
@XmlElement(name = "Key", namespace = HeliosHandler27.HELIOS_URI)
protected String keyCode;
public String getKeyCode() {
return keyCode;
}
public void setKeyCode(String code) {
this.keyCode = code;
}
}

View File

@@ -0,0 +1,57 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
/**
* The {@link SOAPObjectFactory} is a helper class that is used to generate JAXB
* Elements
*
* @author Karel Goderis - Initial contribution
*/
@XmlRegistry
public class SOAPObjectFactory {
private static final QName DATA_QNAME = new QName(HeliosHandler27.HELIOS_URI, "Data");
@XmlElementDecl(namespace = HeliosHandler27.HELIOS_URI, name = "CallStateChanged")
public JAXBElement<SOAPCallStateChanged> createHeliosCallStateChanged(SOAPCallStateChanged value) {
return new JAXBElement<>(DATA_QNAME, SOAPCallStateChanged.class, null, value);
}
@XmlElementDecl(namespace = HeliosHandler27.HELIOS_URI, name = "CodeEntered")
public JAXBElement<SOAPCodeEntered> createHeliosCodeEntered(SOAPCodeEntered value) {
return new JAXBElement<>(DATA_QNAME, SOAPCodeEntered.class, null, value);
}
@XmlElementDecl(namespace = HeliosHandler27.HELIOS_URI, name = "CardEntered")
public JAXBElement<SOAPCardEntered> createHeliosCardEntered(SOAPCardEntered value) {
return new JAXBElement<>(DATA_QNAME, SOAPCardEntered.class, null, value);
}
@XmlElementDecl(namespace = HeliosHandler27.HELIOS_URI, name = "DeviceState")
public JAXBElement<SOAPDeviceState> createHeliosDeviceState(SOAPDeviceState value) {
return new JAXBElement<>(DATA_QNAME, SOAPDeviceState.class, null, value);
}
@XmlElementDecl(namespace = HeliosHandler27.HELIOS_URI, name = "KeyPressed")
public JAXBElement<SOAPKeyPressed> createHeliosKeyPressedd(SOAPKeyPressed value) {
return new JAXBElement<>(DATA_QNAME, SOAPKeyPressed.class, null, value);
}
}

View File

@@ -0,0 +1,73 @@
/**
* 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.helios.internal.ws.soap;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.openhab.binding.helios.internal.handler.HeliosHandler27;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link SOAPSubscriptionActionHandler} is a custom SOAP handler that modifies
* some SOAP headers in order to get the Helios comm. working
*
* @author Karel Goderis - Initial contribution
*/
public class SOAPSubscriptionActionHandler extends SOAPActionHandler {
private Logger logger = LoggerFactory.getLogger(SOAPSubscriptionActionHandler.class);
private HeliosHandler27 handler;
public SOAPSubscriptionActionHandler(HeliosHandler27 heliosHandler) {
this.handler = heliosHandler;
}
@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (isRequest) {
try {
SOAPMessage soapMsg = context.getMessage();
SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnv.getHeader();
if (soapHeader == null) {
soapHeader = soapEnv.addHeader();
}
QName qname = new QName("http://www.2n.cz/2013/event", "SubscriptionId");
SOAPHeaderElement soapHeaderElement = soapHeader.addHeaderElement(qname);
soapHeaderElement.addAttribute(
new QName("http://www.w3.org/2005/08/addressing", "IsReferenceParameter"), "true");
if (handler.getSubscriptionID() != null) {
soapHeaderElement.addTextNode(handler.getSubscriptionID());
}
soapMsg.saveChanges();
} catch (Exception e) {
logger.debug("An exception occurred while formatting a SOAP header : '{}'", e.getMessage());
}
}
return true;
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="helios" 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>Helios Binding</name>
<description>This is the binding for Helios IP (Vario/...) class of intercom/(video)doorstations.</description>
<author>Karel Goderis</author>
</binding:binding>

View File

@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="helios"
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">
<!-- Helios Channel Types -->
<channel-type id="audiolooptest" advanced="true">
<item-type>Switch</item-type>
<label>Audio Loop Test</label>
<description>Audio loop test result</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="audioloopteststamp">
<item-type>DateTime</item-type>
<label>Audio Loop Test Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="callstate">
<item-type>String</item-type>
<label>Call State</label>
<description>State of the current call</description>
<state readOnly="true">
<options>
<option value="ringing">Ringing</option>
<option value="connected">Connected</option>
<option value="terminated">Terminated</option>
</options>
</state>
</channel-type>
<channel-type id="calldirection" advanced="true">
<item-type>String</item-type>
<label>Call Direction</label>
<description>Direction of the current call</description>
<state readOnly="true">
<options>
<option value="incoming">Incoming</option>
<option value="outgoing">Outgoing</option>
</options>
</state>
</channel-type>
<channel-type id="callstatestamp">
<item-type>DateTime</item-type>
<label>Call State Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="card">
<kind>trigger</kind>
<label>Card ID</label>
<description>Detected card identification with a 24-64-bit number in the hexadecimal format</description>
</channel-type>
<channel-type id="cardvalid" advanced="true">
<item-type>Switch</item-type>
<label>Card Valid</label>
<description>If the detected card is valid, the parameter value is ON. If not, the parameter is set to OFF</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="cardstamp">
<item-type>DateTime</item-type>
<label>Card Detection Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="code">
<kind>trigger</kind>
<label>Code Entered</label>
<description>Numerical code entered, e.g. 1234.</description>
</channel-type>
<channel-type id="codevalid" advanced="true">
<item-type>Switch</item-type>
<label>Code Valid</label>
<description>If the entered code is valid, the parameter value is ON. If not, the parameter is set to OFF</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="codestamp">
<item-type>DateTime</item-type>
<label>Code Entered Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="devicestate">
<item-type>String</item-type>
<label>Device State</label>
<description>State of the Helios device</description>
<state readOnly="true">
<options>
<option value="startup">Startup</option>
</options>
</state>
</channel-type>
<channel-type id="devicestatestamp">
<item-type>DateTime</item-type>
<label>Device State Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="keypressed">
<kind>trigger</kind>
<label>Key Pressed</label>
<description>The key pressed, 0, 1, …, 9, *, # for keypad buttons and %1..%54 for call buttons</description>
</channel-type>
<channel-type id="keypressedstamp">
<item-type>DateTime</item-type>
<label>Key Press Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="keyreleased">
<kind>trigger</kind>
<label>Key Released</label>
<description>The key released, 0, 1, …, 9, *, # for keypad buttons and %1..%54 for call buttons</description>
</channel-type>
<channel-type id="keyreleasedstamp">
<item-type>DateTime</item-type>
<label>Key Released Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="motion">
<item-type>Switch</item-type>
<label>Motion</label>
<description>Motion detection indicator</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="motionstamp">
<item-type>DateTime</item-type>
<label>Motion Detection Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="noise">
<item-type>Switch</item-type>
<label>Noise</label>
<description>Noise detection indicator</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="noisestamp">
<item-type>DateTime</item-type>
<label>Noise Detection Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="switchstate">
<item-type>Switch</item-type>
<label>Switch State</label>
<description>ON when a switch switched on, OFF when a switch switched off</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="switchstateswitch">
<item-type>Number</item-type>
<label>Switch Number</label>
<description>Number of the switch that switched, e.g. 1 to 4</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="switchstateoriginator">
<item-type>String</item-type>
<label>Switch State Originator</label>
<description>Originator that switched the switch</description>
<state readOnly="true">
<options>
<option value="DTMF">DTMF</option>
<option value="API">API</option>
</options>
</state>
</channel-type>
<channel-type id="switchstatestamp">
<item-type>DateTime</item-type>
<label>Switch Switch Time</label>
<description>Event date and time in CCYY-MM-DDThh:mm:ss format</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="switchenabler" advanced="true">
<item-type>Switch</item-type>
<label>Switch Enabler</label>
<description>Enable or disable a switch</description>
</channel-type>
<channel-type id="switchtrigger" advanced="true">
<item-type>Switch</item-type>
<label>Switch Trigger</label>
<description>Switch a switch</description>
</channel-type>
<channel-type id="io" advanced="true">
<item-type>Switch</item-type>
<label>IO</label>
<description>Enable or disable the output of an I/O port of the Helios device</description>
</channel-type>
</thing:thing-descriptions>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="helios"
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="ipvario221">
<label>Helios IP Vario</label>
<description>Helios IP Vario Door Station / Intercom with Firmware v2.21</description>
<channels>
<channel id="audiolooptest" typeId="audiolooptest"/>
<channel id="audioloopteststamp" typeId="audioloopteststamp"/>
<channel id="callstate" typeId="callstate"/>
<channel id="calldirection" typeId="calldirection"/>
<channel id="callstatestamp" typeId="callstatestamp"/>
<channel id="card" typeId="card"/>
<channel id="cardvalid" typeId="cardvalid"/>
<channel id="cardstamp" typeId="cardstamp"/>
<channel id="code" typeId="code"/>
<channel id="codevalid" typeId="codevalid"/>
<channel id="codestamp" typeId="codestamp"/>
<channel id="devicestate" typeId="devicestate"/>
<channel id="devicestatestamp" typeId="devicestatestamp"/>
<channel id="keypressed" typeId="keypressed"/>
<channel id="keypressedstamp" typeId="keypressedstamp"/>
<channel id="keyreleased" typeId="keyreleased"/>
<channel id="keyreleasedstamp" typeId="keyreleasedstamp"/>
<channel id="motion" typeId="motion"/>
<channel id="motionstamp" typeId="motionstamp"/>
<channel id="noise" typeId="noise"/>
<channel id="noisestamp" typeId="noisestamp"/>
<channel id="switchstate" typeId="switchstate"/>
<channel id="switchstateswitch" typeId="switchstateswitch"/>
<channel id="switchstateoriginator" typeId="switchstateoriginator"/>
<channel id="switchstatestamp" typeId="switchstatestamp"/>
</channels>
<config-description>
<parameter name="ipAddress" type="text" required="true">
<context>network-address</context>
<label>Network Address</label>
<description>Network address of the Helios IP device</description>
</parameter>
<parameter name="username" type="text" required="true">
<label>Username</label>
<description>Username to access REST services on the Helios IP device</description>
</parameter>
<parameter name="password" type="text" required="true">
<context>password</context>
<label>Password</label>
<description>Password to access REST services on the Helios IP device</description>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="helios"
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="ipvario27">
<label>Helios IP Vario</label>
<description>Helios IP Vario Door Station / Intercom with Firmware v2.7</description>
<channels>
<channel id="keypressed" typeId="keypressed"/>
<channel id="keypressedstamp" typeId="keypressedstamp"/>
<channel id="callstate" typeId="callstate"/>
<channel id="calldirection" typeId="calldirection"/>
<channel id="callstatestamp" typeId="callstatestamp"/>
<channel id="card" typeId="card"/>
<channel id="cardvalid" typeId="cardvalid"/>
<channel id="cardstamp" typeId="cardstamp"/>
<channel id="code" typeId="code"/>
<channel id="codevalid" typeId="codevalid"/>
<channel id="codestamp" typeId="codestamp"/>
<channel id="devicestate" typeId="devicestate"/>
<channel id="devicestatestamp" typeId="devicestatestamp"/>
</channels>
<config-description>
<parameter name="ipAddress" type="text" required="true">
<context>network-address</context>
<label>Network Address</label>
<description>Network address of the Helios IP device</description>
</parameter>
<parameter name="openHABipAddress" type="text" required="true">
<context>network-address</context>
<label>Network Address</label>
<description>Network address of the openHAB host</description>
</parameter>
<parameter name="openHABportNumber" type="integer" required="true">
<label>Port Number</label>
<description>TCP port number the notification web service will be registered on</description>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>